| author | |
| committer | |
| log | 3405a64dd8fdf3affe14c057692484fffb63b0af |
| tree | 7a9d4be187f3f4b47e6108867bc917b71dca1886 |
| parent | 1cba2f64d39073bb77faac7234e88f52aa395643 |
| signature | Signed by PGP key B5690EEEBB952194 |
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: Julius Marminge <julius@macmini.local>
Co-authored-by: codex <codex@users.noreply.github.com>174 files changed, 1853 insertions(+), 1870 deletions(-)
apps/desktop/src/clientPersistence.test.ts+1-1| ... | @@ -58,7 +58,7 @@ const clientSettings: ClientSettings = { | ... | @@ -58,7 +58,7 @@ const clientSettings: ClientSettings = { |
| 58 | }; | 58 | }; |
| 59 | 59 | ||
| 60 | const savedRegistryRecord: PersistedSavedEnvironmentRecord = { | 60 | const savedRegistryRecord: PersistedSavedEnvironmentRecord = { |
| 61 | environmentId: EnvironmentId.makeUnsafe("environment-1"), | 61 | environmentId: EnvironmentId.make("environment-1"), |
| 62 | label: "Remote environment", | 62 | label: "Remote environment", |
| 63 | httpBaseUrl: "https://remote.example.com/", | 63 | httpBaseUrl: "https://remote.example.com/", |
| 64 | wsBaseUrl: "wss://remote.example.com/", | 64 | wsBaseUrl: "wss://remote.example.com/", |
apps/server/integration/OrchestrationEngineHarness.integration.ts+1-1| ... | @@ -438,7 +438,7 @@ export const makeOrchestrationIntegrationHarness = ( | ... | @@ -438,7 +438,7 @@ export const makeOrchestrationIntegrationHarness = ( |
| 438 | ) => | 438 | ) => |
| 439 | waitFor( | 439 | waitFor( |
| 440 | pendingApprovalRepository | 440 | pendingApprovalRepository |
| 441 | .getByRequestId({ requestId: ApprovalRequestId.makeUnsafe(requestId) }) | 441 | .getByRequestId({ requestId: ApprovalRequestId.make(requestId) }) |
| 442 | .pipe( | 442 | .pipe( |
| 443 | Effect.map((row) => | 443 | Effect.map((row) => |
| 444 | Option.match(row, { | 444 | Option.match(row, { |
apps/server/integration/TestProviderAdapter.integration.ts+3-3| ... | @@ -289,7 +289,7 @@ export const makeTestProviderAdapterHarness = (options?: MakeTestProviderAdapter | ... | @@ -289,7 +289,7 @@ export const makeTestProviderAdapterHarness = (options?: MakeTestProviderAdapter |
| 289 | 289 | ||
| 290 | state.turnCount += 1; | 290 | state.turnCount += 1; |
| 291 | const turnCount = state.turnCount; | 291 | const turnCount = state.turnCount; |
| 292 | const turnId = TurnId.makeUnsafe(`turn-${turnCount}`); | 292 | const turnId = TurnId.make(`turn-${turnCount}`); |
| 293 | 293 | ||
| 294 | const response = state.queuedResponses.shift(); | 294 | const response = state.queuedResponses.shift(); |
| 295 | if (!response) { | 295 | if (!response) { |
| ... | @@ -307,7 +307,7 @@ export const makeTestProviderAdapterHarness = (options?: MakeTestProviderAdapter | ... | @@ -307,7 +307,7 @@ export const makeTestProviderAdapterHarness = (options?: MakeTestProviderAdapter |
| 307 | ...(fixtureEvent as Record<string, unknown>), | 307 | ...(fixtureEvent as Record<string, unknown>), |
| 308 | eventId: randomUUID(), | 308 | eventId: randomUUID(), |
| 309 | provider, | 309 | provider, |
| 310 | sessionId: RuntimeSessionId.makeUnsafe(String(input.threadId)), | 310 | sessionId: RuntimeSessionId.make(String(input.threadId)), |
| 311 | createdAt: nowIso(), | 311 | createdAt: nowIso(), |
| 312 | }; | 312 | }; |
| 313 | rawEvent.threadId = state.snapshot.threadId; | 313 | rawEvent.threadId = state.snapshot.threadId; |
| ... | @@ -363,7 +363,7 @@ export const makeTestProviderAdapterHarness = (options?: MakeTestProviderAdapter | ... | @@ -363,7 +363,7 @@ export const makeTestProviderAdapterHarness = (options?: MakeTestProviderAdapter |
| 363 | if (deferredTurnCompletedEvents.length === 0) { | 363 | if (deferredTurnCompletedEvents.length === 0) { |
| 364 | yield* emit({ | 364 | yield* emit({ |
| 365 | type: "turn.completed", | 365 | type: "turn.completed", |
| 366 | eventId: EventId.makeUnsafe(randomUUID()), | 366 | eventId: EventId.make(randomUUID()), |
| 367 | provider, | 367 | provider, |
| 368 | createdAt: nowIso(), | 368 | createdAt: nowIso(), |
| 369 | threadId: state.snapshot.threadId, | 369 | threadId: state.snapshot.threadId, |
apps/server/integration/fixtures/providerRuntime.ts+2-2| ... | @@ -5,14 +5,14 @@ const PROVIDER = "codex" as const; | ... | @@ -5,14 +5,14 @@ const PROVIDER = "codex" as const; |
| 5 | const SESSION_ID = "fixture-session"; | 5 | const SESSION_ID = "fixture-session"; |
| 6 | const THREAD_ID = "fixture-thread"; | 6 | const THREAD_ID = "fixture-thread"; |
| 7 | const TURN_ID = "fixture-turn"; | 7 | const TURN_ID = "fixture-turn"; |
| 8 | const REQUEST_ID = RuntimeRequestId.makeUnsafe("req-1"); | 8 | const REQUEST_ID = RuntimeRequestId.make("req-1"); |
| 9 | 9 | ||
| 10 | function baseEvent( | 10 | function baseEvent( |
| 11 | eventId: string, | 11 | eventId: string, |
| 12 | createdAt: string, | 12 | createdAt: string, |
| 13 | ): Pick<LegacyProviderRuntimeEvent, "eventId" | "provider" | "sessionId" | "createdAt"> { | 13 | ): Pick<LegacyProviderRuntimeEvent, "eventId" | "provider" | "sessionId" | "createdAt"> { |
| 14 | return { | 14 | return { |
| 15 | eventId: EventId.makeUnsafe(eventId), | 15 | eventId: EventId.make(eventId), |
| 16 | provider: PROVIDER, | 16 | provider: PROVIDER, |
| 17 | sessionId: SESSION_ID, | 17 | sessionId: SESSION_ID, |
| 18 | createdAt, | 18 | createdAt, |
apps/server/integration/orchestrationEngine.integration.test.ts+18-19| ... | @@ -30,14 +30,13 @@ import type { | ... | @@ -30,14 +30,13 @@ import type { |
| 30 | } from "../src/orchestration/Services/RuntimeReceiptBus.ts"; | 30 | } from "../src/orchestration/Services/RuntimeReceiptBus.ts"; |
| 31 | import * as NodeServices from "@effect/platform-node/NodeServices"; | 31 | import * as NodeServices from "@effect/platform-node/NodeServices"; |
| 32 | 32 | ||
| 33 | const asMessageId = (value: string): MessageId => MessageId.makeUnsafe(value); | 33 | const asMessageId = (value: string): MessageId => MessageId.make(value); |
| 34 | const asProjectId = (value: string): ProjectId => ProjectId.makeUnsafe(value); | 34 | const asProjectId = (value: string): ProjectId => ProjectId.make(value); |
| 35 | const asEventId = (value: string): EventId => EventId.makeUnsafe(value); | 35 | const asEventId = (value: string): EventId => EventId.make(value); |
| 36 | const asApprovalRequestId = (value: string): ApprovalRequestId => | 36 | const asApprovalRequestId = (value: string): ApprovalRequestId => ApprovalRequestId.make(value); |
| 37 | ApprovalRequestId.makeUnsafe(value); | ||
| 38 | 37 | ||
| 39 | const PROJECT_ID = asProjectId("project-1"); | 38 | const PROJECT_ID = asProjectId("project-1"); |
| 40 | const THREAD_ID = ThreadId.makeUnsafe("thread-1"); | 39 | const THREAD_ID = ThreadId.make("thread-1"); |
| 41 | const FIXTURE_TURN_ID = "fixture-turn"; | 40 | const FIXTURE_TURN_ID = "fixture-turn"; |
| 42 | const APPROVAL_REQUEST_ID = asApprovalRequestId("req-approval-1"); | 41 | const APPROVAL_REQUEST_ID = asApprovalRequestId("req-approval-1"); |
| 43 | type IntegrationProvider = ProviderKind; | 42 | type IntegrationProvider = ProviderKind; |
| ... | @@ -112,7 +111,7 @@ const seedProjectAndThread = (harness: OrchestrationIntegrationHarness) => | ... | @@ -112,7 +111,7 @@ const seedProjectAndThread = (harness: OrchestrationIntegrationHarness) => |
| 112 | 111 | ||
| 113 | yield* harness.engine.dispatch({ | 112 | yield* harness.engine.dispatch({ |
| 114 | type: "project.create", | 113 | type: "project.create", |
| 115 | commandId: CommandId.makeUnsafe("cmd-project-create"), | 114 | commandId: CommandId.make("cmd-project-create"), |
| 116 | projectId: PROJECT_ID, | 115 | projectId: PROJECT_ID, |
| 117 | title: "Integration Project", | 116 | title: "Integration Project", |
| 118 | workspaceRoot: harness.workspaceDir, | 117 | workspaceRoot: harness.workspaceDir, |
| ... | @@ -125,7 +124,7 @@ const seedProjectAndThread = (harness: OrchestrationIntegrationHarness) => | ... | @@ -125,7 +124,7 @@ const seedProjectAndThread = (harness: OrchestrationIntegrationHarness) => |
| 125 | 124 | ||
| 126 | yield* harness.engine.dispatch({ | 125 | yield* harness.engine.dispatch({ |
| 127 | type: "thread.create", | 126 | type: "thread.create", |
| 128 | commandId: CommandId.makeUnsafe("cmd-thread-create"), | 127 | commandId: CommandId.make("cmd-thread-create"), |
| 129 | threadId: THREAD_ID, | 128 | threadId: THREAD_ID, |
| 130 | projectId: PROJECT_ID, | 129 | projectId: PROJECT_ID, |
| 131 | title: "Integration Thread", | 130 | title: "Integration Thread", |
| ... | @@ -150,7 +149,7 @@ const startTurn = (input: { | ... | @@ -150,7 +149,7 @@ const startTurn = (input: { |
| 150 | }) => | 149 | }) => |
| 151 | input.harness.engine.dispatch({ | 150 | input.harness.engine.dispatch({ |
| 152 | type: "thread.turn.start", | 151 | type: "thread.turn.start", |
| 153 | commandId: CommandId.makeUnsafe(input.commandId), | 152 | commandId: CommandId.make(input.commandId), |
| 154 | threadId: THREAD_ID, | 153 | threadId: THREAD_ID, |
| 155 | message: { | 154 | message: { |
| 156 | messageId: asMessageId(input.messageId), | 155 | messageId: asMessageId(input.messageId), |
| ... | @@ -261,7 +260,7 @@ it.live.skipIf(!process.env.CODEX_BINARY_PATH)( | ... | @@ -261,7 +260,7 @@ it.live.skipIf(!process.env.CODEX_BINARY_PATH)( |
| 261 | 260 | ||
| 262 | yield* harness.engine.dispatch({ | 261 | yield* harness.engine.dispatch({ |
| 263 | type: "project.create", | 262 | type: "project.create", |
| 264 | commandId: CommandId.makeUnsafe("cmd-project-create-real-codex"), | 263 | commandId: CommandId.make("cmd-project-create-real-codex"), |
| 265 | projectId: PROJECT_ID, | 264 | projectId: PROJECT_ID, |
| 266 | title: "Integration Project", | 265 | title: "Integration Project", |
| 267 | workspaceRoot: harness.workspaceDir, | 266 | workspaceRoot: harness.workspaceDir, |
| ... | @@ -274,7 +273,7 @@ it.live.skipIf(!process.env.CODEX_BINARY_PATH)( | ... | @@ -274,7 +273,7 @@ it.live.skipIf(!process.env.CODEX_BINARY_PATH)( |
| 274 | 273 | ||
| 275 | yield* harness.engine.dispatch({ | 274 | yield* harness.engine.dispatch({ |
| 276 | type: "thread.create", | 275 | type: "thread.create", |
| 277 | commandId: CommandId.makeUnsafe("cmd-thread-create-real-codex"), | 276 | commandId: CommandId.make("cmd-thread-create-real-codex"), |
| 278 | threadId: THREAD_ID, | 277 | threadId: THREAD_ID, |
| 279 | projectId: PROJECT_ID, | 278 | projectId: PROJECT_ID, |
| 280 | title: "Integration Thread", | 279 | title: "Integration Thread", |
| ... | @@ -291,7 +290,7 @@ it.live.skipIf(!process.env.CODEX_BINARY_PATH)( | ... | @@ -291,7 +290,7 @@ it.live.skipIf(!process.env.CODEX_BINARY_PATH)( |
| 291 | 290 | ||
| 292 | yield* harness.engine.dispatch({ | 291 | yield* harness.engine.dispatch({ |
| 293 | type: "thread.turn.start", | 292 | type: "thread.turn.start", |
| 294 | commandId: CommandId.makeUnsafe("cmd-turn-start-real-codex-1"), | 293 | commandId: CommandId.make("cmd-turn-start-real-codex-1"), |
| 295 | threadId: THREAD_ID, | 294 | threadId: THREAD_ID, |
| 296 | message: { | 295 | message: { |
| 297 | messageId: asMessageId("msg-real-codex-1"), | 296 | messageId: asMessageId("msg-real-codex-1"), |
| ... | @@ -318,7 +317,7 @@ it.live.skipIf(!process.env.CODEX_BINARY_PATH)( | ... | @@ -318,7 +317,7 @@ it.live.skipIf(!process.env.CODEX_BINARY_PATH)( |
| 318 | 317 | ||
| 319 | yield* harness.engine.dispatch({ | 318 | yield* harness.engine.dispatch({ |
| 320 | type: "thread.turn.start", | 319 | type: "thread.turn.start", |
| 321 | commandId: CommandId.makeUnsafe("cmd-turn-start-real-codex-2"), | 320 | commandId: CommandId.make("cmd-turn-start-real-codex-2"), |
| 322 | threadId: THREAD_ID, | 321 | threadId: THREAD_ID, |
| 323 | message: { | 322 | message: { |
| 324 | messageId: asMessageId("msg-real-codex-2"), | 323 | messageId: asMessageId("msg-real-codex-2"), |
| ... | @@ -583,7 +582,7 @@ it.live("tracks approval requests and resolves pending approvals on user respons | ... | @@ -583,7 +582,7 @@ it.live("tracks approval requests and resolves pending approvals on user respons |
| 583 | 582 | ||
| 584 | yield* harness.engine.dispatch({ | 583 | yield* harness.engine.dispatch({ |
| 585 | type: "thread.approval.respond", | 584 | type: "thread.approval.respond", |
| 586 | commandId: CommandId.makeUnsafe("cmd-approval-respond"), | 585 | commandId: CommandId.make("cmd-approval-respond"), |
| 587 | threadId: THREAD_ID, | 586 | threadId: THREAD_ID, |
| 588 | requestId: APPROVAL_REQUEST_ID, | 587 | requestId: APPROVAL_REQUEST_ID, |
| 589 | decision: "accept", | 588 | decision: "accept", |
| ... | @@ -815,7 +814,7 @@ it.live("reverts to an earlier checkpoint and trims checkpoint projections + git | ... | @@ -815,7 +814,7 @@ it.live("reverts to an earlier checkpoint and trims checkpoint projections + git |
| 815 | 814 | ||
| 816 | yield* harness.engine.dispatch({ | 815 | yield* harness.engine.dispatch({ |
| 817 | type: "thread.checkpoint.revert", | 816 | type: "thread.checkpoint.revert", |
| 818 | commandId: CommandId.makeUnsafe("cmd-checkpoint-revert"), | 817 | commandId: CommandId.make("cmd-checkpoint-revert"), |
| 819 | threadId: THREAD_ID, | 818 | threadId: THREAD_ID, |
| 820 | turnCount: 1, | 819 | turnCount: 1, |
| 821 | createdAt: nowIso(), | 820 | createdAt: nowIso(), |
| ... | @@ -875,7 +874,7 @@ it.live( | ... | @@ -875,7 +874,7 @@ it.live( |
| 875 | 874 | ||
| 876 | yield* harness.engine.dispatch({ | 875 | yield* harness.engine.dispatch({ |
| 877 | type: "thread.checkpoint.revert", | 876 | type: "thread.checkpoint.revert", |
| 878 | commandId: CommandId.makeUnsafe("cmd-checkpoint-revert-no-session"), | 877 | commandId: CommandId.make("cmd-checkpoint-revert-no-session"), |
| 879 | threadId: THREAD_ID, | 878 | threadId: THREAD_ID, |
| 880 | turnCount: 0, | 879 | turnCount: 0, |
| 881 | createdAt: nowIso(), | 880 | createdAt: nowIso(), |
| ... | @@ -1119,7 +1118,7 @@ it.live("forwards claudeAgent approval responses to the provider session", () => | ... | @@ -1119,7 +1118,7 @@ it.live("forwards claudeAgent approval responses to the provider session", () => |
| 1119 | 1118 | ||
| 1120 | yield* harness.engine.dispatch({ | 1119 | yield* harness.engine.dispatch({ |
| 1121 | type: "thread.approval.respond", | 1120 | type: "thread.approval.respond", |
| 1122 | commandId: CommandId.makeUnsafe("cmd-claude-approval-respond"), | 1121 | commandId: CommandId.make("cmd-claude-approval-respond"), |
| 1123 | threadId: THREAD_ID, | 1122 | threadId: THREAD_ID, |
| 1124 | requestId: APPROVAL_REQUEST_ID, | 1123 | requestId: APPROVAL_REQUEST_ID, |
| 1125 | decision: "accept", | 1124 | decision: "accept", |
| ... | @@ -1192,7 +1191,7 @@ it.live("forwards thread.turn.interrupt to claudeAgent provider sessions", () => | ... | @@ -1192,7 +1191,7 @@ it.live("forwards thread.turn.interrupt to claudeAgent provider sessions", () => |
| 1192 | 1191 | ||
| 1193 | yield* harness.engine.dispatch({ | 1192 | yield* harness.engine.dispatch({ |
| 1194 | type: "thread.turn.interrupt", | 1193 | type: "thread.turn.interrupt", |
| 1195 | commandId: CommandId.makeUnsafe("cmd-turn-interrupt-claude"), | 1194 | commandId: CommandId.make("cmd-turn-interrupt-claude"), |
| 1196 | threadId: THREAD_ID, | 1195 | threadId: THREAD_ID, |
| 1197 | createdAt: nowIso(), | 1196 | createdAt: nowIso(), |
| 1198 | }); | 1197 | }); |
| ... | @@ -1309,7 +1308,7 @@ it.live("reverts claudeAgent turns and rolls back provider conversation state", | ... | @@ -1309,7 +1308,7 @@ it.live("reverts claudeAgent turns and rolls back provider conversation state", |
| 1309 | 1308 | ||
| 1310 | yield* harness.engine.dispatch({ | 1309 | yield* harness.engine.dispatch({ |
| 1311 | type: "thread.checkpoint.revert", | 1310 | type: "thread.checkpoint.revert", |
| 1312 | commandId: CommandId.makeUnsafe("cmd-checkpoint-revert-claude"), | 1311 | commandId: CommandId.make("cmd-checkpoint-revert-claude"), |
| 1313 | threadId: THREAD_ID, | 1312 | threadId: THREAD_ID, |
| 1314 | turnCount: 1, | 1313 | turnCount: 1, |
| 1315 | createdAt: nowIso(), | 1314 | createdAt: nowIso(), |
apps/server/integration/providerService.integration.test.ts+24-36| ... | @@ -122,15 +122,12 @@ it.live("replays typed runtime fixture events", () => | ... | @@ -122,15 +122,12 @@ it.live("replays typed runtime fixture events", () => |
| 122 | 122 | ||
| 123 | yield* Effect.gen(function* () { | 123 | yield* Effect.gen(function* () { |
| 124 | const provider = yield* ProviderService; | 124 | const provider = yield* ProviderService; |
| 125 | const session = yield* provider.startSession( | 125 | const session = yield* provider.startSession(ThreadId.make("thread-integration-typed"), { |
| 126 | ThreadId.makeUnsafe("thread-integration-typed"), | 126 | threadId: ThreadId.make("thread-integration-typed"), |
| 127 | { | 127 | provider: "codex", |
| 128 | threadId: ThreadId.makeUnsafe("thread-integration-typed"), | 128 | cwd: fixture.cwd, |
| 129 | provider: "codex", | 129 | runtimeMode: "full-access", |
| 130 | cwd: fixture.cwd, | 130 | }); |
| 131 | runtimeMode: "full-access", | ||
| 132 | }, | ||
| 133 | ); | ||
| 134 | assert.equal((session.threadId ?? "").length > 0, true); | 131 | assert.equal((session.threadId ?? "").length > 0, true); |
| 135 | 132 | ||
| 136 | const observedEvents = yield* runTurn({ | 133 | const observedEvents = yield* runTurn({ |
| ... | @@ -157,15 +154,12 @@ it.live("replays file-changing fixture turn events", () => | ... | @@ -157,15 +154,12 @@ it.live("replays file-changing fixture turn events", () => |
| 157 | 154 | ||
| 158 | yield* Effect.gen(function* () { | 155 | yield* Effect.gen(function* () { |
| 159 | const provider = yield* ProviderService; | 156 | const provider = yield* ProviderService; |
| 160 | const session = yield* provider.startSession( | 157 | const session = yield* provider.startSession(ThreadId.make("thread-integration-tools"), { |
| 161 | ThreadId.makeUnsafe("thread-integration-tools"), | 158 | threadId: ThreadId.make("thread-integration-tools"), |
| 162 | { | 159 | provider: "codex", |
| 163 | threadId: ThreadId.makeUnsafe("thread-integration-tools"), | 160 | cwd: fixture.cwd, |
| 164 | provider: "codex", | 161 | runtimeMode: "full-access", |
| 165 | cwd: fixture.cwd, | 162 | }); |
| 166 | runtimeMode: "full-access", | ||
| 167 | }, | ||
| 168 | ); | ||
| 169 | assert.equal((session.threadId ?? "").length > 0, true); | 163 | assert.equal((session.threadId ?? "").length > 0, true); |
| 170 | 164 | ||
| 171 | const observedEvents = yield* runTurn({ | 165 | const observedEvents = yield* runTurn({ |
| ... | @@ -196,15 +190,12 @@ it.live("runs multi-turn tool/approval flow", () => | ... | @@ -196,15 +190,12 @@ it.live("runs multi-turn tool/approval flow", () => |
| 196 | 190 | ||
| 197 | yield* Effect.gen(function* () { | 191 | yield* Effect.gen(function* () { |
| 198 | const provider = yield* ProviderService; | 192 | const provider = yield* ProviderService; |
| 199 | const session = yield* provider.startSession( | 193 | const session = yield* provider.startSession(ThreadId.make("thread-integration-multi"), { |
| 200 | ThreadId.makeUnsafe("thread-integration-multi"), | 194 | threadId: ThreadId.make("thread-integration-multi"), |
| 201 | { | 195 | provider: "codex", |
| 202 | threadId: ThreadId.makeUnsafe("thread-integration-multi"), | 196 | cwd: fixture.cwd, |
| 203 | provider: "codex", | 197 | runtimeMode: "full-access", |
| 204 | cwd: fixture.cwd, | 198 | }); |
| 205 | runtimeMode: "full-access", | ||
| 206 | }, | ||
| 207 | ); | ||
| 208 | assert.equal((session.threadId ?? "").length > 0, true); | 199 | assert.equal((session.threadId ?? "").length > 0, true); |
| 209 | 200 | ||
| 210 | const firstTurnEvents = yield* runTurn({ | 201 | const firstTurnEvents = yield* runTurn({ |
| ... | @@ -250,15 +241,12 @@ it.live("rolls back provider conversation state only", () => | ... | @@ -250,15 +241,12 @@ it.live("rolls back provider conversation state only", () => |
| 250 | 241 | ||
| 251 | yield* Effect.gen(function* () { | 242 | yield* Effect.gen(function* () { |
| 252 | const provider = yield* ProviderService; | 243 | const provider = yield* ProviderService; |
| 253 | const session = yield* provider.startSession( | 244 | const session = yield* provider.startSession(ThreadId.make("thread-integration-rollback"), { |
| 254 | ThreadId.makeUnsafe("thread-integration-rollback"), | 245 | threadId: ThreadId.make("thread-integration-rollback"), |
| 255 | { | 246 | provider: "codex", |
| 256 | threadId: ThreadId.makeUnsafe("thread-integration-rollback"), | 247 | cwd: fixture.cwd, |
| 257 | provider: "codex", | 248 | runtimeMode: "full-access", |
| 258 | cwd: fixture.cwd, | 249 | }); |
| 259 | runtimeMode: "full-access", | ||
| 260 | }, | ||
| 261 | ); | ||
| 262 | assert.equal((session.threadId ?? "").length > 0, true); | 250 | assert.equal((session.threadId ?? "").length > 0, true); |
| 263 | 251 | ||
| 264 | yield* runTurn({ | 252 | yield* runTurn({ |
apps/server/src/auth/Layers/SessionCredentialService.ts+1-1| ... | @@ -188,7 +188,7 @@ export const makeSessionCredentialService = Effect.gen(function* () { | ... | @@ -188,7 +188,7 @@ export const makeSessionCredentialService = Effect.gen(function* () { |
| 188 | 188 | ||
| 189 | const issue: SessionCredentialServiceShape["issue"] = (input) => | 189 | const issue: SessionCredentialServiceShape["issue"] = (input) => |
| 190 | Effect.gen(function* () { | 190 | Effect.gen(function* () { |
| 191 | const sessionId = AuthSessionId.makeUnsafe(crypto.randomUUID()); | 191 | const sessionId = AuthSessionId.make(crypto.randomUUID()); |
| 192 | const issuedAt = yield* DateTime.now; | 192 | const issuedAt = yield* DateTime.now; |
| 193 | const expiresAt = DateTime.add(issuedAt, { | 193 | const expiresAt = DateTime.add(issuedAt, { |
| 194 | milliseconds: Duration.toMillis(input?.ttl ?? DEFAULT_SESSION_TTL), | 194 | milliseconds: Duration.toMillis(input?.ttl ?? DEFAULT_SESSION_TTL), |
apps/server/src/auth/Services/AuthControlPlane.ts+2-2| ... | @@ -4,7 +4,7 @@ import type { | ... | @@ -4,7 +4,7 @@ import type { |
| 4 | AuthPairingLink, | 4 | AuthPairingLink, |
| 5 | AuthSessionId, | 5 | AuthSessionId, |
| 6 | } from "@t3tools/contracts"; | 6 | } from "@t3tools/contracts"; |
| 7 | import { Data, DateTime, Duration, Effect, ServiceMap } from "effect"; | 7 | import { Data, DateTime, Duration, Effect, Context } from "effect"; |
| 8 | import { SessionRole } from "./SessionCredentialService"; | 8 | import { SessionRole } from "./SessionCredentialService"; |
| 9 | 9 | ||
| 10 | export const DEFAULT_SESSION_SUBJECT = "cli-issued-session"; | 10 | export const DEFAULT_SESSION_SUBJECT = "cli-issued-session"; |
| ... | @@ -64,6 +64,6 @@ export interface AuthControlPlaneShape { | ... | @@ -64,6 +64,6 @@ export interface AuthControlPlaneShape { |
| 64 | ) => Effect.Effect<number, AuthControlPlaneError>; | 64 | ) => Effect.Effect<number, AuthControlPlaneError>; |
| 65 | } | 65 | } |
| 66 | 66 | ||
| 67 | export class AuthControlPlane extends ServiceMap.Service<AuthControlPlane, AuthControlPlaneShape>()( | 67 | export class AuthControlPlane extends Context.Service<AuthControlPlane, AuthControlPlaneShape>()( |
| 68 | "t3/AuthControlPlane", | 68 | "t3/AuthControlPlane", |
| 69 | ) {} | 69 | ) {} |
apps/server/src/auth/Services/BootstrapCredentialService.ts+2-2| ... | @@ -1,5 +1,5 @@ | ... | @@ -1,5 +1,5 @@ |
| 1 | import type { AuthPairingLink, ServerAuthBootstrapMethod } from "@t3tools/contracts"; | 1 | import type { AuthPairingLink, ServerAuthBootstrapMethod } from "@t3tools/contracts"; |
| 2 | import { Data, DateTime, Duration, ServiceMap } from "effect"; | 2 | import { Data, DateTime, Duration, Context } from "effect"; |
| 3 | import type { Effect, Stream } from "effect"; | 3 | import type { Effect, Stream } from "effect"; |
| 4 | 4 | ||
| 5 | export type BootstrapCredentialRole = "owner" | "client"; | 5 | export type BootstrapCredentialRole = "owner" | "client"; |
| ... | @@ -51,7 +51,7 @@ export interface BootstrapCredentialServiceShape { | ... | @@ -51,7 +51,7 @@ export interface BootstrapCredentialServiceShape { |
| 51 | readonly consume: (credential: string) => Effect.Effect<BootstrapGrant, BootstrapCredentialError>; | 51 | readonly consume: (credential: string) => Effect.Effect<BootstrapGrant, BootstrapCredentialError>; |
| 52 | } | 52 | } |
| 53 | 53 | ||
| 54 | export class BootstrapCredentialService extends ServiceMap.Service< | 54 | export class BootstrapCredentialService extends Context.Service< |
| 55 | BootstrapCredentialService, | 55 | BootstrapCredentialService, |
| 56 | BootstrapCredentialServiceShape | 56 | BootstrapCredentialServiceShape |
| 57 | >()("t3/auth/Services/BootstrapCredentialService") {} | 57 | >()("t3/auth/Services/BootstrapCredentialService") {} |
apps/server/src/auth/Services/ServerAuth.ts+2-2| ... | @@ -12,7 +12,7 @@ import type { | ... | @@ -12,7 +12,7 @@ import type { |
| 12 | ServerAuthSessionMethod, | 12 | ServerAuthSessionMethod, |
| 13 | AuthWebSocketTokenResult, | 13 | AuthWebSocketTokenResult, |
| 14 | } from "@t3tools/contracts"; | 14 | } from "@t3tools/contracts"; |
| 15 | import { Data, DateTime, ServiceMap } from "effect"; | 15 | import { Data, DateTime, Context } from "effect"; |
| 16 | import type { Effect } from "effect"; | 16 | import type { Effect } from "effect"; |
| 17 | import type * as HttpServerRequest from "effect/unstable/http/HttpServerRequest"; | 17 | import type * as HttpServerRequest from "effect/unstable/http/HttpServerRequest"; |
| 18 | import type { SessionRole } from "./SessionCredentialService.ts"; | 18 | import type { SessionRole } from "./SessionCredentialService.ts"; |
| ... | @@ -79,6 +79,6 @@ export interface ServerAuthShape { | ... | @@ -79,6 +79,6 @@ export interface ServerAuthShape { |
| 79 | readonly issueStartupPairingUrl: (baseUrl: string) => Effect.Effect<string, AuthError>; | 79 | readonly issueStartupPairingUrl: (baseUrl: string) => Effect.Effect<string, AuthError>; |
| 80 | } | 80 | } |
| 81 | 81 | ||
| 82 | export class ServerAuth extends ServiceMap.Service<ServerAuth, ServerAuthShape>()( | 82 | export class ServerAuth extends Context.Service<ServerAuth, ServerAuthShape>()( |
| 83 | "t3/auth/Services/ServerAuth", | 83 | "t3/auth/Services/ServerAuth", |
| 84 | ) {} | 84 | ) {} |
apps/server/src/auth/Services/ServerAuthPolicy.ts+2-2| ... | @@ -1,11 +1,11 @@ | ... | @@ -1,11 +1,11 @@ |
| 1 | import type { ServerAuthDescriptor } from "@t3tools/contracts"; | 1 | import type { ServerAuthDescriptor } from "@t3tools/contracts"; |
| 2 | import { ServiceMap } from "effect"; | 2 | import { Context } from "effect"; |
| 3 | import type { Effect } from "effect"; | 3 | import type { Effect } from "effect"; |
| 4 | 4 | ||
| 5 | export interface ServerAuthPolicyShape { | 5 | export interface ServerAuthPolicyShape { |
| 6 | readonly getDescriptor: () => Effect.Effect<ServerAuthDescriptor>; | 6 | readonly getDescriptor: () => Effect.Effect<ServerAuthDescriptor>; |
| 7 | } | 7 | } |
| 8 | 8 | ||
| 9 | export class ServerAuthPolicy extends ServiceMap.Service<ServerAuthPolicy, ServerAuthPolicyShape>()( | 9 | export class ServerAuthPolicy extends Context.Service<ServerAuthPolicy, ServerAuthPolicyShape>()( |
| 10 | "t3/auth/Services/ServerAuthPolicy", | 10 | "t3/auth/Services/ServerAuthPolicy", |
| 11 | ) {} | 11 | ) {} |
apps/server/src/auth/Services/ServerSecretStore.ts+4-5| ... | @@ -1,4 +1,4 @@ | ... | @@ -1,4 +1,4 @@ |
| 1 | import { Data, ServiceMap } from "effect"; | 1 | import { Data, Context } from "effect"; |
| 2 | import type { Effect } from "effect"; | 2 | import type { Effect } from "effect"; |
| 3 | 3 | ||
| 4 | export class SecretStoreError extends Data.TaggedError("SecretStoreError")<{ | 4 | export class SecretStoreError extends Data.TaggedError("SecretStoreError")<{ |
| ... | @@ -16,7 +16,6 @@ export interface ServerSecretStoreShape { | ... | @@ -16,7 +16,6 @@ export interface ServerSecretStoreShape { |
| 16 | readonly remove: (name: string) => Effect.Effect<void, SecretStoreError>; | 16 | readonly remove: (name: string) => Effect.Effect<void, SecretStoreError>; |
| 17 | } | 17 | } |
| 18 | 18 | ||
| 19 | export class ServerSecretStore extends ServiceMap.Service< | 19 | export class ServerSecretStore extends Context.Service<ServerSecretStore, ServerSecretStoreShape>()( |
| 20 | ServerSecretStore, | 20 | "t3/auth/Services/ServerSecretStore", |
| 21 | ServerSecretStoreShape | 21 | ) {} |
| 22 | >()("t3/auth/Services/ServerSecretStore") {} |
apps/server/src/auth/Services/SessionCredentialService.ts+2-2| ... | @@ -4,7 +4,7 @@ import type { | ... | @@ -4,7 +4,7 @@ import type { |
| 4 | AuthSessionId, | 4 | AuthSessionId, |
| 5 | ServerAuthSessionMethod, | 5 | ServerAuthSessionMethod, |
| 6 | } from "@t3tools/contracts"; | 6 | } from "@t3tools/contracts"; |
| 7 | import { Data, DateTime, Duration, ServiceMap } from "effect"; | 7 | import { Data, DateTime, Duration, Context } from "effect"; |
| 8 | import type { Effect, Stream } from "effect"; | 8 | import type { Effect, Stream } from "effect"; |
| 9 | 9 | ||
| 10 | export type SessionRole = "owner" | "client"; | 10 | export type SessionRole = "owner" | "client"; |
| ... | @@ -81,7 +81,7 @@ export interface SessionCredentialServiceShape { | ... | @@ -81,7 +81,7 @@ export interface SessionCredentialServiceShape { |
| 81 | readonly markDisconnected: (sessionId: AuthSessionId) => Effect.Effect<void, never>; | 81 | readonly markDisconnected: (sessionId: AuthSessionId) => Effect.Effect<void, never>; |
| 82 | } | 82 | } |
| 83 | 83 | ||
| 84 | export class SessionCredentialService extends ServiceMap.Service< | 84 | export class SessionCredentialService extends Context.Service< |
| 85 | SessionCredentialService, | 85 | SessionCredentialService, |
| 86 | SessionCredentialServiceShape | 86 | SessionCredentialServiceShape |
| 87 | >()("t3/auth/Services/SessionCredentialService") {} | 87 | >()("t3/auth/Services/SessionCredentialService") {} |
apps/server/src/checkpointing/Layers/CheckpointDiffQuery.test.ts+4-4| ... | @@ -26,7 +26,7 @@ function makeThreadCheckpointContext(input: { | ... | @@ -26,7 +26,7 @@ function makeThreadCheckpointContext(input: { |
| 26 | worktreePath: input.worktreePath, | 26 | worktreePath: input.worktreePath, |
| 27 | checkpoints: [ | 27 | checkpoints: [ |
| 28 | { | 28 | { |
| 29 | turnId: TurnId.makeUnsafe("turn-1"), | 29 | turnId: TurnId.make("turn-1"), |
| 30 | checkpointTurnCount: input.checkpointTurnCount, | 30 | checkpointTurnCount: input.checkpointTurnCount, |
| 31 | checkpointRef: input.checkpointRef, | 31 | checkpointRef: input.checkpointRef, |
| 32 | status: "ready", | 32 | status: "ready", |
| ... | @@ -40,8 +40,8 @@ function makeThreadCheckpointContext(input: { | ... | @@ -40,8 +40,8 @@ function makeThreadCheckpointContext(input: { |
| 40 | 40 | ||
| 41 | describe("CheckpointDiffQueryLive", () => { | 41 | describe("CheckpointDiffQueryLive", () => { |
| 42 | it("computes diffs using canonical turn-0 checkpoint refs", async () => { | 42 | it("computes diffs using canonical turn-0 checkpoint refs", async () => { |
| 43 | const projectId = ProjectId.makeUnsafe("project-1"); | 43 | const projectId = ProjectId.make("project-1"); |
| 44 | const threadId = ThreadId.makeUnsafe("thread-1"); | 44 | const threadId = ThreadId.make("thread-1"); |
| 45 | const toCheckpointRef = checkpointRefForThreadTurn(threadId, 1); | 45 | const toCheckpointRef = checkpointRefForThreadTurn(threadId, 1); |
| 46 | const hasCheckpointRefCalls: Array<CheckpointRef> = []; | 46 | const hasCheckpointRefCalls: Array<CheckpointRef> = []; |
| 47 | const diffCheckpointsCalls: Array<{ | 47 | const diffCheckpointsCalls: Array<{ |
| ... | @@ -119,7 +119,7 @@ describe("CheckpointDiffQueryLive", () => { | ... | @@ -119,7 +119,7 @@ describe("CheckpointDiffQueryLive", () => { |
| 119 | }); | 119 | }); |
| 120 | 120 | ||
| 121 | it("fails when the thread is missing from the snapshot", async () => { | 121 | it("fails when the thread is missing from the snapshot", async () => { |
| 122 | const threadId = ThreadId.makeUnsafe("thread-missing"); | 122 | const threadId = ThreadId.make("thread-missing"); |
| 123 | 123 | ||
| 124 | const checkpointStore: CheckpointStoreShape = { | 124 | const checkpointStore: CheckpointStoreShape = { |
| 125 | isGitRepository: () => Effect.succeed(true), | 125 | isGitRepository: () => Effect.succeed(true), |
apps/server/src/checkpointing/Layers/CheckpointStore.test.ts+1-1| ... | @@ -93,7 +93,7 @@ it.layer(TestLayer)("CheckpointStoreLive", (it) => { | ... | @@ -93,7 +93,7 @@ it.layer(TestLayer)("CheckpointStoreLive", (it) => { |
| 93 | const tmp = yield* makeTmpDir(); | 93 | const tmp = yield* makeTmpDir(); |
| 94 | yield* initRepoWithCommit(tmp); | 94 | yield* initRepoWithCommit(tmp); |
| 95 | const checkpointStore = yield* CheckpointStore; | 95 | const checkpointStore = yield* CheckpointStore; |
| 96 | const threadId = ThreadId.makeUnsafe("thread-checkpoint-store"); | 96 | const threadId = ThreadId.make("thread-checkpoint-store"); |
| 97 | const fromCheckpointRef = checkpointRefForThreadTurn(threadId, 0); | 97 | const fromCheckpointRef = checkpointRefForThreadTurn(threadId, 0); |
| 98 | const toCheckpointRef = checkpointRefForThreadTurn(threadId, 1); | 98 | const toCheckpointRef = checkpointRefForThreadTurn(threadId, 1); |
| 99 | 99 |
apps/server/src/checkpointing/Services/CheckpointDiffQuery.ts+2-2| ... | @@ -12,7 +12,7 @@ import type { | ... | @@ -12,7 +12,7 @@ import type { |
| 12 | OrchestrationGetTurnDiffInput, | 12 | OrchestrationGetTurnDiffInput, |
| 13 | OrchestrationGetTurnDiffResult, | 13 | OrchestrationGetTurnDiffResult, |
| 14 | } from "@t3tools/contracts"; | 14 | } from "@t3tools/contracts"; |
| 15 | import { ServiceMap } from "effect"; | 15 | import { Context } from "effect"; |
| 16 | import type { Effect } from "effect"; | 16 | import type { Effect } from "effect"; |
| 17 | 17 | ||
| 18 | import type { CheckpointServiceError } from "../Errors.ts"; | 18 | import type { CheckpointServiceError } from "../Errors.ts"; |
| ... | @@ -43,7 +43,7 @@ export interface CheckpointDiffQueryShape { | ... | @@ -43,7 +43,7 @@ export interface CheckpointDiffQueryShape { |
| 43 | /** | 43 | /** |
| 44 | * CheckpointDiffQuery - Service tag for checkpoint diff queries. | 44 | * CheckpointDiffQuery - Service tag for checkpoint diff queries. |
| 45 | */ | 45 | */ |
| 46 | export class CheckpointDiffQuery extends ServiceMap.Service< | 46 | export class CheckpointDiffQuery extends Context.Service< |
| 47 | CheckpointDiffQuery, | 47 | CheckpointDiffQuery, |
| 48 | CheckpointDiffQueryShape | 48 | CheckpointDiffQueryShape |
| 49 | >()("t3/checkpointing/Services/CheckpointDiffQuery") {} | 49 | >()("t3/checkpointing/Services/CheckpointDiffQuery") {} |
apps/server/src/checkpointing/Services/CheckpointStore.ts+3-3| ... | @@ -5,12 +5,12 @@ | ... | @@ -5,12 +5,12 @@ |
| 5 | * workspace thread timeline. It does not store user-facing checkpoint metadata | 5 | * workspace thread timeline. It does not store user-facing checkpoint metadata |
| 6 | * and does not coordinate provider conversation rollback. | 6 | * and does not coordinate provider conversation rollback. |
| 7 | * | 7 | * |
| 8 | * Uses Effect `ServiceMap.Service` for dependency injection and exposes typed | 8 | * Uses Effect `Context.Service` for dependency injection and exposes typed |
| 9 | * domain errors for checkpoint storage operations. | 9 | * domain errors for checkpoint storage operations. |
| 10 | * | 10 | * |
| 11 | * @module CheckpointStore | 11 | * @module CheckpointStore |
| 12 | */ | 12 | */ |
| 13 | import { ServiceMap } from "effect"; | 13 | import { Context } from "effect"; |
| 14 | import type { Effect } from "effect"; | 14 | import type { Effect } from "effect"; |
| 15 | 15 | ||
| 16 | import type { CheckpointStoreError } from "../Errors.ts"; | 16 | import type { CheckpointStoreError } from "../Errors.ts"; |
| ... | @@ -95,6 +95,6 @@ export interface CheckpointStoreShape { | ... | @@ -95,6 +95,6 @@ export interface CheckpointStoreShape { |
| 95 | /** | 95 | /** |
| 96 | * CheckpointStore - Service tag for checkpoint persistence and restore operations. | 96 | * CheckpointStore - Service tag for checkpoint persistence and restore operations. |
| 97 | */ | 97 | */ |
| 98 | export class CheckpointStore extends ServiceMap.Service<CheckpointStore, CheckpointStoreShape>()( | 98 | export class CheckpointStore extends Context.Service<CheckpointStore, CheckpointStoreShape>()( |
| 99 | "t3/checkpointing/Services/CheckpointStore", | 99 | "t3/checkpointing/Services/CheckpointStore", |
| 100 | ) {} | 100 | ) {} |
apps/server/src/checkpointing/Utils.ts+1-1| ... | @@ -4,7 +4,7 @@ import { CheckpointRef, ProjectId, type ThreadId } from "@t3tools/contracts"; | ... | @@ -4,7 +4,7 @@ import { CheckpointRef, ProjectId, type ThreadId } from "@t3tools/contracts"; |
| 4 | export const CHECKPOINT_REFS_PREFIX = "refs/t3/checkpoints"; | 4 | export const CHECKPOINT_REFS_PREFIX = "refs/t3/checkpoints"; |
| 5 | 5 | ||
| 6 | export function checkpointRefForThreadTurn(threadId: ThreadId, turnCount: number): CheckpointRef { | 6 | export function checkpointRefForThreadTurn(threadId: ThreadId, turnCount: number): CheckpointRef { |
| 7 | return CheckpointRef.makeUnsafe( | 7 | return CheckpointRef.make( |
| 8 | `${CHECKPOINT_REFS_PREFIX}/${Encoding.encodeBase64Url(threadId)}/turn/${turnCount}`, | 8 | `${CHECKPOINT_REFS_PREFIX}/${Encoding.encodeBase64Url(threadId)}/turn/${turnCount}`, |
| 9 | ); | 9 | ); |
| 10 | } | 10 | } |
apps/server/src/cli-config.test.ts+63| ... | @@ -153,6 +153,69 @@ it.layer(NodeServices.layer)("cli config resolution", (it) => { | ... | @@ -153,6 +153,69 @@ it.layer(NodeServices.layer)("cli config resolution", (it) => { |
| 153 | }), | 153 | }), |
| 154 | ); | 154 | ); |
| 155 | 155 | ||
| 156 | it.effect("preserves explicit false CLI boolean flags over env and bootstrap values", () => | ||
| 157 | Effect.gen(function* () { | ||
| 158 | const { join } = yield* Path.Path; | ||
| 159 | const baseDir = join(os.tmpdir(), "t3-cli-config-false-flags"); | ||
| 160 | const fd = yield* openBootstrapFd({ | ||
| 161 | noBrowser: true, | ||
| 162 | autoBootstrapProjectFromCwd: true, | ||
| 163 | logWebSocketEvents: true, | ||
| 164 | }); | ||
| 165 | const derivedPaths = yield* deriveServerPaths(baseDir, new URL("http://127.0.0.1:4173")); | ||
| 166 | |||
| 167 | const resolved = yield* resolveServerConfig( | ||
| 168 | { | ||
| 169 | mode: Option.some("web"), | ||
| 170 | port: Option.some(8788), | ||
| 171 | host: Option.some("127.0.0.1"), | ||
| 172 | baseDir: Option.some(baseDir), | ||
| 173 | cwd: Option.none(), | ||
| 174 | devUrl: Option.some(new URL("http://127.0.0.1:4173")), | ||
| 175 | noBrowser: Option.some(false), | ||
| 176 | bootstrapFd: Option.none(), | ||
| 177 | autoBootstrapProjectFromCwd: Option.some(false), | ||
| 178 | logWebSocketEvents: Option.some(false), | ||
| 179 | }, | ||
| 180 | Option.none(), | ||
| 181 | ).pipe( | ||
| 182 | Effect.provide( | ||
| 183 | Layer.mergeAll( | ||
| 184 | ConfigProvider.layer( | ||
| 185 | ConfigProvider.fromEnv({ | ||
| 186 | env: { | ||
| 187 | T3CODE_BOOTSTRAP_FD: String(fd), | ||
| 188 | T3CODE_NO_BROWSER: "true", | ||
| 189 | T3CODE_AUTO_BOOTSTRAP_PROJECT_FROM_CWD: "true", | ||
| 190 | T3CODE_LOG_WS_EVENTS: "true", | ||
| 191 | }, | ||
| 192 | }), | ||
| 193 | ), | ||
| 194 | NetService.layer, | ||
| 195 | ), | ||
| 196 | ), | ||
| 197 | ); | ||
| 198 | |||
| 199 | expect(resolved).toEqual({ | ||
| 200 | logLevel: "Info", | ||
| 201 | ...defaultObservabilityConfig, | ||
| 202 | mode: "web", | ||
| 203 | port: 8788, | ||
| 204 | cwd: process.cwd(), | ||
| 205 | baseDir, | ||
| 206 | ...derivedPaths, | ||
| 207 | host: "127.0.0.1", | ||
| 208 | staticDir: undefined, | ||
| 209 | devUrl: new URL("http://127.0.0.1:4173"), | ||
| 210 | noBrowser: false, | ||
| 211 | startupPresentation: "browser", | ||
| 212 | desktopBootstrapToken: undefined, | ||
| 213 | autoBootstrapProjectFromCwd: false, | ||
| 214 | logWebSocketEvents: false, | ||
| 215 | }); | ||
| 216 | }), | ||
| 217 | ); | ||
| 218 | |||
| 156 | it.effect("uses bootstrap envelope values as fallbacks when flags and env are absent", () => | 219 | it.effect("uses bootstrap envelope values as fallbacks when flags and env are absent", () => |
| 157 | Effect.gen(function* () { | 220 | Effect.gen(function* () { |
| 158 | const { join } = yield* Path.Path; | 221 | const { join } = yield* Path.Path; |
apps/server/src/cli.test.ts+4| ... | @@ -152,6 +152,10 @@ it.layer(NodeServices.layer)("cli log-level parsing", (it) => { | ... | @@ -152,6 +152,10 @@ it.layer(NodeServices.layer)("cli log-level parsing", (it) => { |
| 152 | runCliWithRuntime(["--log-level", "debug", "--version"]), | 152 | runCliWithRuntime(["--log-level", "debug", "--version"]), |
| 153 | ); | 153 | ); |
| 154 | 154 | ||
| 155 | it.effect("accepts canonical --no-<flag> boolean negation", () => | ||
| 156 | runCliWithRuntime(["--no-log-websocket-events", "--version"]), | ||
| 157 | ); | ||
| 158 | |||
| 155 | it.effect("rejects invalid log-level casing before launching the server", () => | 159 | it.effect("rejects invalid log-level casing before launching the server", () => |
| 156 | Effect.gen(function* () { | 160 | Effect.gen(function* () { |
| 157 | const error = yield* runCliWithRuntime(["--log-level", "Debug"]).pipe(Effect.flip); | 161 | const error = yield* runCliWithRuntime(["--log-level", "Debug"]).pipe(Effect.flip); |
apps/server/src/cli.ts+37-68| ... | @@ -193,9 +193,6 @@ interface CliAuthLocationFlags { | ... | @@ -193,9 +193,6 @@ interface CliAuthLocationFlags { |
| 193 | readonly devUrl?: Option.Option<URL>; | 193 | readonly devUrl?: Option.Option<URL>; |
| 194 | } | 194 | } |
| 195 | 195 | ||
| 196 | const resolveBooleanFlag = (flag: Option.Option<boolean>, envValue: boolean) => | ||
| 197 | Option.getOrElse(Option.filter(flag, Boolean), () => envValue); | ||
| 198 | |||
| 199 | const resolveOptionPrecedence = <Value>( | 196 | const resolveOptionPrecedence = <Value>( |
| 200 | ...values: ReadonlyArray<Option.Option<Value>> | 197 | ...values: ReadonlyArray<Option.Option<Value>> |
| 201 | ): Option.Option<Value> => Option.firstSomeOf(values); | 198 | ): Option.Option<Value> => Option.firstSomeOf(values); |
| ... | @@ -241,12 +238,13 @@ export const resolveServerConfig = ( | ... | @@ -241,12 +238,13 @@ export const resolveServerConfig = ( |
| 241 | bootstrapFd !== undefined | 238 | bootstrapFd !== undefined |
| 242 | ? yield* readBootstrapEnvelope(BootstrapEnvelopeSchema, bootstrapFd) | 239 | ? yield* readBootstrapEnvelope(BootstrapEnvelopeSchema, bootstrapFd) |
| 243 | : Option.none(); | 240 | : Option.none(); |
| 241 | const bootstrap = Option.getOrUndefined(bootstrapEnvelope); | ||
| 244 | 242 | ||
| 245 | const mode: RuntimeMode = Option.getOrElse( | 243 | const mode: RuntimeMode = Option.getOrElse( |
| 246 | resolveOptionPrecedence( | 244 | resolveOptionPrecedence( |
| 247 | normalizedFlags.mode, | 245 | normalizedFlags.mode, |
| 248 | Option.fromUndefinedOr(env.mode), | 246 | Option.fromUndefinedOr(env.mode), |
| 249 | Option.flatMap(bootstrapEnvelope, (bootstrap) => Option.fromUndefinedOr(bootstrap.mode)), | 247 | Option.fromUndefinedOr(bootstrap?.mode), |
| 250 | ), | 248 | ), |
| 251 | () => "web", | 249 | () => "web", |
| 252 | ); | 250 | ); |
| ... | @@ -255,7 +253,7 @@ export const resolveServerConfig = ( | ... | @@ -255,7 +253,7 @@ export const resolveServerConfig = ( |
| 255 | resolveOptionPrecedence( | 253 | resolveOptionPrecedence( |
| 256 | normalizedFlags.port, | 254 | normalizedFlags.port, |
| 257 | Option.fromUndefinedOr(env.port), | 255 | Option.fromUndefinedOr(env.port), |
| 258 | Option.flatMap(bootstrapEnvelope, (bootstrap) => Option.fromUndefinedOr(bootstrap.port)), | 256 | Option.fromUndefinedOr(bootstrap?.port), |
| 259 | ), | 257 | ), |
| 260 | { | 258 | { |
| 261 | onSome: (value) => Effect.succeed(value), | 259 | onSome: (value) => Effect.succeed(value), |
| ... | @@ -271,7 +269,7 @@ export const resolveServerConfig = ( | ... | @@ -271,7 +269,7 @@ export const resolveServerConfig = ( |
| 271 | resolveOptionPrecedence( | 269 | resolveOptionPrecedence( |
| 272 | normalizedFlags.devUrl, | 270 | normalizedFlags.devUrl, |
| 273 | Option.fromUndefinedOr(env.devUrl), | 271 | Option.fromUndefinedOr(env.devUrl), |
| 274 | Option.flatMap(bootstrapEnvelope, (bootstrap) => Option.fromUndefinedOr(bootstrap.devUrl)), | 272 | Option.fromUndefinedOr(bootstrap?.devUrl), |
| 275 | ), | 273 | ), |
| 276 | () => undefined, | 274 | () => undefined, |
| 277 | ); | 275 | ); |
| ... | @@ -280,9 +278,7 @@ export const resolveServerConfig = ( | ... | @@ -280,9 +278,7 @@ export const resolveServerConfig = ( |
| 280 | resolveOptionPrecedence( | 278 | resolveOptionPrecedence( |
| 281 | normalizedFlags.baseDir, | 279 | normalizedFlags.baseDir, |
| 282 | Option.fromUndefinedOr(env.t3Home), | 280 | Option.fromUndefinedOr(env.t3Home), |
| 283 | Option.flatMap(bootstrapEnvelope, (bootstrap) => | 281 | Option.fromUndefinedOr(bootstrap?.t3Home), |
| 284 | Option.fromUndefinedOr(bootstrap.t3Home), | ||
| 285 | ), | ||
| 286 | ), | 282 | ), |
| 287 | ), | 283 | ), |
| 288 | ); | 284 | ); |
| ... | @@ -297,60 +293,41 @@ export const resolveServerConfig = ( | ... | @@ -297,60 +293,41 @@ export const resolveServerConfig = ( |
| 297 | const serverTracePath = env.traceFile ?? derivedPaths.serverTracePath; | 293 | const serverTracePath = env.traceFile ?? derivedPaths.serverTracePath; |
| 298 | yield* fs.makeDirectory(path.dirname(serverTracePath), { recursive: true }); | 294 | yield* fs.makeDirectory(path.dirname(serverTracePath), { recursive: true }); |
| 299 | const startupPresentation = options?.startupPresentation ?? "browser"; | 295 | const startupPresentation = options?.startupPresentation ?? "browser"; |
| 300 | const noBrowser = | 296 | const isHeadlessStartup = startupPresentation === "headless"; |
| 301 | startupPresentation === "headless" | 297 | const noBrowser = Option.getOrElse( |
| 302 | ? true | 298 | resolveOptionPrecedence( |
| 303 | : resolveBooleanFlag( | 299 | isHeadlessStartup ? Option.some(true) : Option.none(), |
| 304 | normalizedFlags.noBrowser, | 300 | normalizedFlags.noBrowser, |
| 305 | Option.getOrElse( | 301 | Option.fromUndefinedOr(env.noBrowser), |
| 306 | resolveOptionPrecedence( | 302 | Option.fromUndefinedOr(bootstrap?.noBrowser), |
| 307 | Option.fromUndefinedOr(env.noBrowser), | ||
| 308 | Option.flatMap(bootstrapEnvelope, (bootstrap) => | ||
| 309 | Option.fromUndefinedOr(bootstrap.noBrowser), | ||
| 310 | ), | ||
| 311 | ), | ||
| 312 | () => mode === "desktop", | ||
| 313 | ), | ||
| 314 | ); | ||
| 315 | const desktopBootstrapToken = Option.getOrUndefined( | ||
| 316 | Option.flatMap(bootstrapEnvelope, (bootstrap) => | ||
| 317 | Option.fromUndefinedOr(bootstrap.desktopBootstrapToken), | ||
| 318 | ), | 303 | ), |
| 304 | () => mode === "desktop", | ||
| 319 | ); | 305 | ); |
| 320 | const autoBootstrapProjectFromCwd = | 306 | const desktopBootstrapToken = bootstrap?.desktopBootstrapToken; |
| 321 | options?.forceAutoBootstrapProjectFromCwd ?? | 307 | const autoBootstrapProjectFromCwd = Option.getOrElse( |
| 322 | (startupPresentation === "headless" | 308 | resolveOptionPrecedence( |
| 323 | ? false | 309 | Option.fromUndefinedOr(options?.forceAutoBootstrapProjectFromCwd), |
| 324 | : resolveBooleanFlag( | 310 | isHeadlessStartup ? Option.some(false) : Option.none(), |
| 325 | normalizedFlags.autoBootstrapProjectFromCwd, | 311 | normalizedFlags.autoBootstrapProjectFromCwd, |
| 326 | Option.getOrElse( | 312 | Option.fromUndefinedOr(env.autoBootstrapProjectFromCwd), |
| 327 | resolveOptionPrecedence( | 313 | Option.fromUndefinedOr(bootstrap?.autoBootstrapProjectFromCwd), |
| 328 | Option.fromUndefinedOr(env.autoBootstrapProjectFromCwd), | 314 | ), |
| 329 | Option.flatMap(bootstrapEnvelope, (bootstrap) => | 315 | () => mode === "web", |
| 330 | Option.fromUndefinedOr(bootstrap.autoBootstrapProjectFromCwd), | 316 | ); |
| 331 | ), | 317 | const logWebSocketEvents = Option.getOrElse( |
| 332 | ), | 318 | resolveOptionPrecedence( |
| 333 | () => mode === "web", | 319 | normalizedFlags.logWebSocketEvents, |
| 334 | ), | 320 | Option.fromUndefinedOr(env.logWebSocketEvents), |
| 335 | )); | 321 | Option.fromUndefinedOr(bootstrap?.logWebSocketEvents), |
| 336 | const logWebSocketEvents = resolveBooleanFlag( | ||
| 337 | normalizedFlags.logWebSocketEvents, | ||
| 338 | Option.getOrElse( | ||
| 339 | resolveOptionPrecedence( | ||
| 340 | Option.fromUndefinedOr(env.logWebSocketEvents), | ||
| 341 | Option.flatMap(bootstrapEnvelope, (bootstrap) => | ||
| 342 | Option.fromUndefinedOr(bootstrap.logWebSocketEvents), | ||
| 343 | ), | ||
| 344 | ), | ||
| 345 | () => Boolean(devUrl), | ||
| 346 | ), | 322 | ), |
| 323 | () => Boolean(devUrl), | ||
| 347 | ); | 324 | ); |
| 348 | const staticDir = devUrl ? undefined : yield* resolveStaticDir(); | 325 | const staticDir = devUrl ? undefined : yield* resolveStaticDir(); |
| 349 | const host = Option.getOrElse( | 326 | const host = Option.getOrElse( |
| 350 | resolveOptionPrecedence( | 327 | resolveOptionPrecedence( |
| 351 | normalizedFlags.host, | 328 | normalizedFlags.host, |
| 352 | Option.fromUndefinedOr(env.host), | 329 | Option.fromUndefinedOr(env.host), |
| 353 | Option.flatMap(bootstrapEnvelope, (bootstrap) => Option.fromUndefinedOr(bootstrap.host)), | 330 | Option.fromUndefinedOr(bootstrap?.host), |
| 354 | ), | 331 | ), |
| 355 | () => (mode === "desktop" ? "127.0.0.1" : undefined), | 332 | () => (mode === "desktop" ? "127.0.0.1" : undefined), |
| 356 | ); | 333 | ); |
| ... | @@ -365,19 +342,11 @@ export const resolveServerConfig = ( | ... | @@ -365,19 +342,11 @@ export const resolveServerConfig = ( |
| 365 | traceMaxFiles: env.traceMaxFiles, | 342 | traceMaxFiles: env.traceMaxFiles, |
| 366 | otlpTracesUrl: | 343 | otlpTracesUrl: |
| 367 | env.otlpTracesUrl ?? | 344 | env.otlpTracesUrl ?? |
| 368 | Option.getOrUndefined( | 345 | bootstrap?.otlpTracesUrl ?? |
| 369 | Option.flatMap(bootstrapEnvelope, (bootstrap) => | ||
| 370 | Option.fromUndefinedOr(bootstrap.otlpTracesUrl), | ||
| 371 | ), | ||
| 372 | ) ?? | ||
| 373 | persistedObservabilitySettings.otlpTracesUrl, | 346 | persistedObservabilitySettings.otlpTracesUrl, |
| 374 | otlpMetricsUrl: | 347 | otlpMetricsUrl: |
| 375 | env.otlpMetricsUrl ?? | 348 | env.otlpMetricsUrl ?? |
| 376 | Option.getOrUndefined( | 349 | bootstrap?.otlpMetricsUrl ?? |
| 377 | Option.flatMap(bootstrapEnvelope, (bootstrap) => | ||
| 378 | Option.fromUndefinedOr(bootstrap.otlpMetricsUrl), | ||
| 379 | ), | ||
| 380 | ) ?? | ||
| 381 | persistedObservabilitySettings.otlpMetricsUrl, | 350 | persistedObservabilitySettings.otlpMetricsUrl, |
| 382 | otlpExportIntervalMs: env.otlpExportIntervalMs, | 351 | otlpExportIntervalMs: env.otlpExportIntervalMs, |
| 383 | otlpServiceName: env.otlpServiceName, | 352 | otlpServiceName: env.otlpServiceName, |
| ... | @@ -1030,10 +999,10 @@ const projectAddCommand = Command.make("add", { | ... | @@ -1030,10 +999,10 @@ const projectAddCommand = Command.make("add", { |
| 1030 | } | 999 | } |
| 1031 | 1000 | ||
| 1032 | const title = yield* resolveProjectTitle(workspaceRoot, Option.getOrUndefined(flags.title)); | 1001 | const title = yield* resolveProjectTitle(workspaceRoot, Option.getOrUndefined(flags.title)); |
| 1033 | const projectId = ProjectId.makeUnsafe(crypto.randomUUID()); | 1002 | const projectId = ProjectId.make(crypto.randomUUID()); |
| 1034 | yield* dispatch({ | 1003 | yield* dispatch({ |
| 1035 | type: "project.create", | 1004 | type: "project.create", |
| 1036 | commandId: CommandId.makeUnsafe(crypto.randomUUID()), | 1005 | commandId: CommandId.make(crypto.randomUUID()), |
| 1037 | projectId, | 1006 | projectId, |
| 1038 | title, | 1007 | title, |
| 1039 | workspaceRoot, | 1008 | workspaceRoot, |
| ... | @@ -1071,7 +1040,7 @@ const projectRemoveCommand = Command.make("remove", { | ... | @@ -1071,7 +1040,7 @@ const projectRemoveCommand = Command.make("remove", { |
| 1071 | }); | 1040 | }); |
| 1072 | yield* dispatch({ | 1041 | yield* dispatch({ |
| 1073 | type: "project.delete", | 1042 | type: "project.delete", |
| 1074 | commandId: CommandId.makeUnsafe(crypto.randomUUID()), | 1043 | commandId: CommandId.make(crypto.randomUUID()), |
| 1075 | projectId: project.id, | 1044 | projectId: project.id, |
| 1076 | }); | 1045 | }); |
| 1077 | return `Removed project ${project.id} (${project.title}).`; | 1046 | return `Removed project ${project.id} (${project.title}).`; |
| ... | @@ -1111,7 +1080,7 @@ const projectRenameCommand = Command.make("rename", { | ... | @@ -1111,7 +1080,7 @@ const projectRenameCommand = Command.make("rename", { |
| 1111 | 1080 | ||
| 1112 | yield* dispatch({ | 1081 | yield* dispatch({ |
| 1113 | type: "project.meta.update", | 1082 | type: "project.meta.update", |
| 1114 | commandId: CommandId.makeUnsafe(crypto.randomUUID()), | 1083 | commandId: CommandId.make(crypto.randomUUID()), |
| 1115 | projectId: project.id, | 1084 | projectId: project.id, |
| 1116 | title: nextTitle, | 1085 | title: nextTitle, |
| 1117 | }); | 1086 | }); |
apps/server/src/codexAppServerManager.test.ts+5-5| ... | @@ -17,7 +17,7 @@ import { | ... | @@ -17,7 +17,7 @@ import { |
| 17 | resolveCodexModelForAccount, | 17 | resolveCodexModelForAccount, |
| 18 | } from "./codexAppServerManager"; | 18 | } from "./codexAppServerManager"; |
| 19 | 19 | ||
| 20 | const asThreadId = (value: string): ThreadId => ThreadId.makeUnsafe(value); | 20 | const asThreadId = (value: string): ThreadId => ThreadId.make(value); |
| 21 | 21 | ||
| 22 | function createSendTurnHarness() { | 22 | function createSendTurnHarness() { |
| 23 | const manager = new CodexAppServerManager(); | 23 | const manager = new CodexAppServerManager(); |
| ... | @@ -111,9 +111,9 @@ function createPendingUserInputHarness() { | ... | @@ -111,9 +111,9 @@ function createPendingUserInputHarness() { |
| 111 | }, | 111 | }, |
| 112 | pendingUserInputs: new Map([ | 112 | pendingUserInputs: new Map([ |
| 113 | [ | 113 | [ |
| 114 | ApprovalRequestId.makeUnsafe("req-user-input-1"), | 114 | ApprovalRequestId.make("req-user-input-1"), |
| 115 | { | 115 | { |
| 116 | requestId: ApprovalRequestId.makeUnsafe("req-user-input-1"), | 116 | requestId: ApprovalRequestId.make("req-user-input-1"), |
| 117 | jsonRpcId: 42, | 117 | jsonRpcId: 42, |
| 118 | threadId: asThreadId("thread_1"), | 118 | threadId: asThreadId("thread_1"), |
| 119 | }, | 119 | }, |
| ... | @@ -743,7 +743,7 @@ describe("respondToUserInput", () => { | ... | @@ -743,7 +743,7 @@ describe("respondToUserInput", () => { |
| 743 | 743 | ||
| 744 | await manager.respondToUserInput( | 744 | await manager.respondToUserInput( |
| 745 | asThreadId("thread_1"), | 745 | asThreadId("thread_1"), |
| 746 | ApprovalRequestId.makeUnsafe("req-user-input-1"), | 746 | ApprovalRequestId.make("req-user-input-1"), |
| 747 | { | 747 | { |
| 748 | scope: "All request methods", | 748 | scope: "All request methods", |
| 749 | compat: "Keep current envelope", | 749 | compat: "Keep current envelope", |
| ... | @@ -780,7 +780,7 @@ describe("respondToUserInput", () => { | ... | @@ -780,7 +780,7 @@ describe("respondToUserInput", () => { |
| 780 | 780 | ||
| 781 | await manager.respondToUserInput( | 781 | await manager.respondToUserInput( |
| 782 | asThreadId("thread_1"), | 782 | asThreadId("thread_1"), |
| 783 | ApprovalRequestId.makeUnsafe("req-user-input-1"), | 783 | ApprovalRequestId.make("req-user-input-1"), |
| 784 | { | 784 | { |
| 785 | scope: [], | 785 | scope: [], |
| 786 | }, | 786 | }, |
apps/server/src/codexAppServerManager.ts+16-16| ... | @@ -19,7 +19,7 @@ import { | ... | @@ -19,7 +19,7 @@ import { |
| 19 | ProviderInteractionMode, | 19 | ProviderInteractionMode, |
| 20 | } from "@t3tools/contracts"; | 20 | } from "@t3tools/contracts"; |
| 21 | import { normalizeModelSlug } from "@t3tools/shared/model"; | 21 | import { normalizeModelSlug } from "@t3tools/shared/model"; |
| 22 | import { Effect, ServiceMap } from "effect"; | 22 | import { Effect, Context } from "effect"; |
| 23 | 23 | ||
| 24 | import { | 24 | import { |
| 25 | formatCodexCliUpgradeMessage, | 25 | formatCodexCliUpgradeMessage, |
| ... | @@ -439,7 +439,7 @@ export class CodexAppServerManager extends EventEmitter<CodexAppServerManagerEve | ... | @@ -439,7 +439,7 @@ export class CodexAppServerManager extends EventEmitter<CodexAppServerManagerEve |
| 439 | private readonly sessions = new Map<ThreadId, CodexSessionContext>(); | 439 | private readonly sessions = new Map<ThreadId, CodexSessionContext>(); |
| 440 | 440 | ||
| 441 | private runPromise: (effect: Effect.Effect<unknown, never>) => Promise<unknown>; | 441 | private runPromise: (effect: Effect.Effect<unknown, never>) => Promise<unknown>; |
| 442 | constructor(services?: ServiceMap.ServiceMap<never>) { | 442 | constructor(services?: Context.Context<never>) { |
| 443 | super(); | 443 | super(); |
| 444 | this.runPromise = services ? Effect.runPromiseWith(services) : Effect.runPromise; | 444 | this.runPromise = services ? Effect.runPromiseWith(services) : Effect.runPromise; |
| 445 | } | 445 | } |
| ... | @@ -640,7 +640,7 @@ export class CodexAppServerManager extends EventEmitter<CodexAppServerManagerEve | ... | @@ -640,7 +640,7 @@ export class CodexAppServerManager extends EventEmitter<CodexAppServerManagerEve |
| 640 | this.stopSession(threadId); | 640 | this.stopSession(threadId); |
| 641 | } else { | 641 | } else { |
| 642 | this.emitEvent({ | 642 | this.emitEvent({ |
| 643 | id: EventId.makeUnsafe(randomUUID()), | 643 | id: EventId.make(randomUUID()), |
| 644 | kind: "error", | 644 | kind: "error", |
| 645 | provider: "codex", | 645 | provider: "codex", |
| 646 | threadId, | 646 | threadId, |
| ... | @@ -739,7 +739,7 @@ export class CodexAppServerManager extends EventEmitter<CodexAppServerManagerEve | ... | @@ -739,7 +739,7 @@ export class CodexAppServerManager extends EventEmitter<CodexAppServerManagerEve |
| 739 | if (!turnIdRaw) { | 739 | if (!turnIdRaw) { |
| 740 | throw new Error("turn/start response did not include a turn id."); | 740 | throw new Error("turn/start response did not include a turn id."); |
| 741 | } | 741 | } |
| 742 | const turnId = TurnId.makeUnsafe(turnIdRaw); | 742 | const turnId = TurnId.make(turnIdRaw); |
| 743 | 743 | ||
| 744 | this.updateSession(context, { | 744 | this.updateSession(context, { |
| 745 | status: "running", | 745 | status: "running", |
| ... | @@ -840,7 +840,7 @@ export class CodexAppServerManager extends EventEmitter<CodexAppServerManagerEve | ... | @@ -840,7 +840,7 @@ export class CodexAppServerManager extends EventEmitter<CodexAppServerManagerEve |
| 840 | }); | 840 | }); |
| 841 | 841 | ||
| 842 | this.emitEvent({ | 842 | this.emitEvent({ |
| 843 | id: EventId.makeUnsafe(randomUUID()), | 843 | id: EventId.make(randomUUID()), |
| 844 | kind: "notification", | 844 | kind: "notification", |
| 845 | provider: "codex", | 845 | provider: "codex", |
| 846 | threadId: context.session.threadId, | 846 | threadId: context.session.threadId, |
| ... | @@ -879,7 +879,7 @@ export class CodexAppServerManager extends EventEmitter<CodexAppServerManagerEve | ... | @@ -879,7 +879,7 @@ export class CodexAppServerManager extends EventEmitter<CodexAppServerManagerEve |
| 879 | }); | 879 | }); |
| 880 | 880 | ||
| 881 | this.emitEvent({ | 881 | this.emitEvent({ |
| 882 | id: EventId.makeUnsafe(randomUUID()), | 882 | id: EventId.make(randomUUID()), |
| 883 | kind: "notification", | 883 | kind: "notification", |
| 884 | provider: "codex", | 884 | provider: "codex", |
| 885 | threadId: context.session.threadId, | 885 | threadId: context.session.threadId, |
| ... | @@ -1061,7 +1061,7 @@ export class CodexAppServerManager extends EventEmitter<CodexAppServerManagerEve | ... | @@ -1061,7 +1061,7 @@ export class CodexAppServerManager extends EventEmitter<CodexAppServerManagerEve |
| 1061 | : undefined; | 1061 | : undefined; |
| 1062 | 1062 | ||
| 1063 | this.emitEvent({ | 1063 | this.emitEvent({ |
| 1064 | id: EventId.makeUnsafe(randomUUID()), | 1064 | id: EventId.make(randomUUID()), |
| 1065 | kind: "notification", | 1065 | kind: "notification", |
| 1066 | provider: "codex", | 1066 | provider: "codex", |
| 1067 | threadId: context.session.threadId, | 1067 | threadId: context.session.threadId, |
| ... | @@ -1134,7 +1134,7 @@ export class CodexAppServerManager extends EventEmitter<CodexAppServerManagerEve | ... | @@ -1134,7 +1134,7 @@ export class CodexAppServerManager extends EventEmitter<CodexAppServerManagerEve |
| 1134 | const requestKind = this.requestKindForMethod(request.method); | 1134 | const requestKind = this.requestKindForMethod(request.method); |
| 1135 | let requestId: ApprovalRequestId | undefined; | 1135 | let requestId: ApprovalRequestId | undefined; |
| 1136 | if (requestKind) { | 1136 | if (requestKind) { |
| 1137 | requestId = ApprovalRequestId.makeUnsafe(randomUUID()); | 1137 | requestId = ApprovalRequestId.make(randomUUID()); |
| 1138 | const pendingRequest: PendingApprovalRequest = { | 1138 | const pendingRequest: PendingApprovalRequest = { |
| 1139 | requestId, | 1139 | requestId, |
| 1140 | jsonRpcId: request.id, | 1140 | jsonRpcId: request.id, |
| ... | @@ -1153,7 +1153,7 @@ export class CodexAppServerManager extends EventEmitter<CodexAppServerManagerEve | ... | @@ -1153,7 +1153,7 @@ export class CodexAppServerManager extends EventEmitter<CodexAppServerManagerEve |
| 1153 | } | 1153 | } |
| 1154 | 1154 | ||
| 1155 | if (request.method === "item/tool/requestUserInput") { | 1155 | if (request.method === "item/tool/requestUserInput") { |
| 1156 | requestId = ApprovalRequestId.makeUnsafe(randomUUID()); | 1156 | requestId = ApprovalRequestId.make(randomUUID()); |
| 1157 | context.pendingUserInputs.set(requestId, { | 1157 | context.pendingUserInputs.set(requestId, { |
| 1158 | requestId, | 1158 | requestId, |
| 1159 | jsonRpcId: request.id, | 1159 | jsonRpcId: request.id, |
| ... | @@ -1164,7 +1164,7 @@ export class CodexAppServerManager extends EventEmitter<CodexAppServerManagerEve | ... | @@ -1164,7 +1164,7 @@ export class CodexAppServerManager extends EventEmitter<CodexAppServerManagerEve |
| 1164 | } | 1164 | } |
| 1165 | 1165 | ||
| 1166 | this.emitEvent({ | 1166 | this.emitEvent({ |
| 1167 | id: EventId.makeUnsafe(randomUUID()), | 1167 | id: EventId.make(randomUUID()), |
| 1168 | kind: "request", | 1168 | kind: "request", |
| 1169 | provider: "codex", | 1169 | provider: "codex", |
| 1170 | threadId: context.session.threadId, | 1170 | threadId: context.session.threadId, |
| ... | @@ -1254,7 +1254,7 @@ export class CodexAppServerManager extends EventEmitter<CodexAppServerManagerEve | ... | @@ -1254,7 +1254,7 @@ export class CodexAppServerManager extends EventEmitter<CodexAppServerManagerEve |
| 1254 | 1254 | ||
| 1255 | private emitLifecycleEvent(context: CodexSessionContext, method: string, message: string): void { | 1255 | private emitLifecycleEvent(context: CodexSessionContext, method: string, message: string): void { |
| 1256 | this.emitEvent({ | 1256 | this.emitEvent({ |
| 1257 | id: EventId.makeUnsafe(randomUUID()), | 1257 | id: EventId.make(randomUUID()), |
| 1258 | kind: "session", | 1258 | kind: "session", |
| 1259 | provider: "codex", | 1259 | provider: "codex", |
| 1260 | threadId: context.session.threadId, | 1260 | threadId: context.session.threadId, |
| ... | @@ -1266,7 +1266,7 @@ export class CodexAppServerManager extends EventEmitter<CodexAppServerManagerEve | ... | @@ -1266,7 +1266,7 @@ export class CodexAppServerManager extends EventEmitter<CodexAppServerManagerEve |
| 1266 | 1266 | ||
| 1267 | private emitErrorEvent(context: CodexSessionContext, method: string, message: string): void { | 1267 | private emitErrorEvent(context: CodexSessionContext, method: string, message: string): void { |
| 1268 | this.emitEvent({ | 1268 | this.emitEvent({ |
| 1269 | id: EventId.makeUnsafe(randomUUID()), | 1269 | id: EventId.make(randomUUID()), |
| 1270 | kind: "error", | 1270 | kind: "error", |
| 1271 | provider: "codex", | 1271 | provider: "codex", |
| 1272 | threadId: context.session.threadId, | 1272 | threadId: context.session.threadId, |
| ... | @@ -1282,7 +1282,7 @@ export class CodexAppServerManager extends EventEmitter<CodexAppServerManagerEve | ... | @@ -1282,7 +1282,7 @@ export class CodexAppServerManager extends EventEmitter<CodexAppServerManagerEve |
| 1282 | message: string, | 1282 | message: string, |
| 1283 | ): void { | 1283 | ): void { |
| 1284 | this.emitEvent({ | 1284 | this.emitEvent({ |
| 1285 | id: EventId.makeUnsafe(randomUUID()), | 1285 | id: EventId.make(randomUUID()), |
| 1286 | kind: "notification", | 1286 | kind: "notification", |
| 1287 | provider: "codex", | 1287 | provider: "codex", |
| 1288 | threadId: context.session.threadId, | 1288 | threadId: context.session.threadId, |
| ... | @@ -1341,7 +1341,7 @@ export class CodexAppServerManager extends EventEmitter<CodexAppServerManagerEve | ... | @@ -1341,7 +1341,7 @@ export class CodexAppServerManager extends EventEmitter<CodexAppServerManagerEve |
| 1341 | const turns = turnsRaw.map((turnValue, index) => { | 1341 | const turns = turnsRaw.map((turnValue, index) => { |
| 1342 | const turn = this.readObject(turnValue); | 1342 | const turn = this.readObject(turnValue); |
| 1343 | const turnIdRaw = this.readString(turn, "id") ?? `${threadIdRaw}:turn:${index + 1}`; | 1343 | const turnIdRaw = this.readString(turn, "id") ?? `${threadIdRaw}:turn:${index + 1}`; |
| 1344 | const turnId = TurnId.makeUnsafe(turnIdRaw); | 1344 | const turnId = TurnId.make(turnIdRaw); |
| 1345 | const items = this.readArray(turn, "items") ?? []; | 1345 | const items = this.readArray(turn, "items") ?? []; |
| 1346 | return { | 1346 | return { |
| 1347 | id: turnId, | 1347 | id: turnId, |
| ... | @@ -1590,9 +1590,9 @@ function readResumeThreadId(input: { | ... | @@ -1590,9 +1590,9 @@ function readResumeThreadId(input: { |
| 1590 | } | 1590 | } |
| 1591 | 1591 | ||
| 1592 | function toTurnId(value: string | undefined): TurnId | undefined { | 1592 | function toTurnId(value: string | undefined): TurnId | undefined { |
| 1593 | return brandIfNonEmpty(value, TurnId.makeUnsafe); | 1593 | return brandIfNonEmpty(value, TurnId.make); |
| 1594 | } | 1594 | } |
| 1595 | 1595 | ||
| 1596 | function toProviderItemId(value: string | undefined): ProviderItemId | undefined { | 1596 | function toProviderItemId(value: string | undefined): ProviderItemId | undefined { |
| 1597 | return brandIfNonEmpty(value, ProviderItemId.makeUnsafe); | 1597 | return brandIfNonEmpty(value, ProviderItemId.make); |
| 1598 | } | 1598 | } |
apps/server/src/config.ts+2-2| ... | @@ -6,7 +6,7 @@ | ... | @@ -6,7 +6,7 @@ |
| 6 | * | 6 | * |
| 7 | * @module ServerConfig | 7 | * @module ServerConfig |
| 8 | */ | 8 | */ |
| 9 | import { Effect, FileSystem, Layer, LogLevel, Path, Schema, ServiceMap } from "effect"; | 9 | import { Effect, FileSystem, Layer, LogLevel, Path, Schema, Context } from "effect"; |
| 10 | 10 | ||
| 11 | export const DEFAULT_PORT = 3773; | 11 | export const DEFAULT_PORT = 3773; |
| 12 | 12 | ||
| ... | @@ -120,7 +120,7 @@ export const ensureServerDirectories = Effect.fn(function* (derivedPaths: Server | ... | @@ -120,7 +120,7 @@ export const ensureServerDirectories = Effect.fn(function* (derivedPaths: Server |
| 120 | /** | 120 | /** |
| 121 | * ServerConfig - Service tag for server runtime configuration. | 121 | * ServerConfig - Service tag for server runtime configuration. |
| 122 | */ | 122 | */ |
| 123 | export class ServerConfig extends ServiceMap.Service<ServerConfig, ServerConfigShape>()( | 123 | export class ServerConfig extends Context.Service<ServerConfig, ServerConfigShape>()( |
| 124 | "t3/config/ServerConfig", | 124 | "t3/config/ServerConfig", |
| 125 | ) { | 125 | ) { |
| 126 | static readonly layerTest = (cwd: string, baseDirOrPrefix: string | { prefix: string }) => | 126 | static readonly layerTest = (cwd: string, baseDirOrPrefix: string | { prefix: string }) => |
apps/server/src/environment/Layers/ServerEnvironment.ts+1-1| ... | @@ -64,7 +64,7 @@ export const makeServerEnvironment = Effect.fn("makeServerEnvironment")(function | ... | @@ -64,7 +64,7 @@ export const makeServerEnvironment = Effect.fn("makeServerEnvironment")(function |
| 64 | return generated; | 64 | return generated; |
| 65 | }); | 65 | }); |
| 66 | 66 | ||
| 67 | const environmentId = EnvironmentId.makeUnsafe(environmentIdRaw); | 67 | const environmentId = EnvironmentId.make(environmentIdRaw); |
| 68 | const cwdBaseName = path.basename(serverConfig.cwd).trim(); | 68 | const cwdBaseName = path.basename(serverConfig.cwd).trim(); |
| 69 | const label = yield* resolveServerEnvironmentLabel({ | 69 | const label = yield* resolveServerEnvironmentLabel({ |
| 70 | cwdBaseName, | 70 | cwdBaseName, |
apps/server/src/environment/Layers/ServerEnvironmentLabel.ts+7-5| ... | @@ -51,11 +51,13 @@ const runFriendlyLabelCommand = Effect.fn("runFriendlyLabelCommand")(function* ( | ... | @@ -51,11 +51,13 @@ const runFriendlyLabelCommand = Effect.fn("runFriendlyLabelCommand")(function* ( |
| 51 | command: string, | 51 | command: string, |
| 52 | args: readonly string[], | 52 | args: readonly string[], |
| 53 | ) { | 53 | ) { |
| 54 | const result = yield* Effect.tryPromise(() => | 54 | const result = yield* Effect.tryPromise({ |
| 55 | runProcess(command, args, { | 55 | try: () => |
| 56 | allowNonZeroExit: true, | 56 | runProcess(command, args, { |
| 57 | }), | 57 | allowNonZeroExit: true, |
| 58 | ).pipe(Effect.orElseSucceed(() => null)); | 58 | }), |
| 59 | catch: () => null, | ||
| 60 | }).pipe(Effect.orElseSucceed(() => null)); | ||
| 59 | 61 | ||
| 60 | if (!result || result.code !== 0) { | 62 | if (!result || result.code !== 0) { |
| 61 | return null; | 63 | return null; |
apps/server/src/environment/Services/ServerEnvironment.ts+4-5| ... | @@ -1,5 +1,5 @@ | ... | @@ -1,5 +1,5 @@ |
| 1 | import type { EnvironmentId, ExecutionEnvironmentDescriptor } from "@t3tools/contracts"; | 1 | import type { EnvironmentId, ExecutionEnvironmentDescriptor } from "@t3tools/contracts"; |
| 2 | import { ServiceMap } from "effect"; | 2 | import { Context } from "effect"; |
| 3 | import type { Effect } from "effect"; | 3 | import type { Effect } from "effect"; |
| 4 | 4 | ||
| 5 | export interface ServerEnvironmentShape { | 5 | export interface ServerEnvironmentShape { |
| ... | @@ -7,7 +7,6 @@ export interface ServerEnvironmentShape { | ... | @@ -7,7 +7,6 @@ export interface ServerEnvironmentShape { |
| 7 | readonly getDescriptor: Effect.Effect<ExecutionEnvironmentDescriptor>; | 7 | readonly getDescriptor: Effect.Effect<ExecutionEnvironmentDescriptor>; |
| 8 | } | 8 | } |
| 9 | 9 | ||
| 10 | export class ServerEnvironment extends ServiceMap.Service< | 10 | export class ServerEnvironment extends Context.Service<ServerEnvironment, ServerEnvironmentShape>()( |
| 11 | ServerEnvironment, | 11 | "t3/environment/Services/ServerEnvironment", |
| 12 | ServerEnvironmentShape | 12 | ) {} |
| 13 | >()("t3/environment/Services/ServerEnvironment") {} |
apps/server/src/git/Layers/GitCore.test.ts+2-2| ... | @@ -649,8 +649,8 @@ it.layer(TestLayer)("git integration", (it) => { | ... | @@ -649,8 +649,8 @@ it.layer(TestLayer)("git integration", (it) => { |
| 649 | 649 | ||
| 650 | it.effect("refreshes upstream behind count after checkout when remote branch advanced", () => | 650 | it.effect("refreshes upstream behind count after checkout when remote branch advanced", () => |
| 651 | Effect.gen(function* () { | 651 | Effect.gen(function* () { |
| 652 | const services = yield* Effect.services(); | 652 | const context = yield* Effect.context<never>(); |
| 653 | const runPromise = Effect.runPromiseWith(services); | 653 | const runPromise = Effect.runPromiseWith(context); |
| 654 | 654 | ||
| 655 | const remote = yield* makeTmpDir(); | 655 | const remote = yield* makeTmpDir(); |
| 656 | const source = yield* makeTmpDir(); | 656 | const source = yield* makeTmpDir(); |
apps/server/src/git/Layers/GitCore.ts+1-2| ... | @@ -933,9 +933,8 @@ export const makeGitCore = Effect.fn("makeGitCore")(function* (options?: { | ... | @@ -933,9 +933,8 @@ export const makeGitCore = Effect.fn("makeGitCore")(function* (options?: { |
| 933 | return true as const; | 933 | return true as const; |
| 934 | }); | 934 | }); |
| 935 | 935 | ||
| 936 | const statusUpstreamRefreshCache = yield* Cache.makeWith({ | 936 | const statusUpstreamRefreshCache = yield* Cache.makeWith(refreshStatusUpstreamCacheEntry, { |
| 937 | capacity: STATUS_UPSTREAM_REFRESH_CACHE_CAPACITY, | 937 | capacity: STATUS_UPSTREAM_REFRESH_CACHE_CAPACITY, |
| 938 | lookup: refreshStatusUpstreamCacheEntry, | ||
| 939 | // Keep successful refreshes warm and briefly back off failed refreshes to avoid retry storms. | 938 | // Keep successful refreshes warm and briefly back off failed refreshes to avoid retry storms. |
| 940 | timeToLive: (exit) => | 939 | timeToLive: (exit) => |
| 941 | Exit.isSuccess(exit) | 940 | Exit.isSuccess(exit) |
apps/server/src/git/Layers/GitManager.ts+2-4| ... | @@ -731,9 +731,8 @@ export const makeGitManager = Effect.fn("makeGitManager")(function* () { | ... | @@ -731,9 +731,8 @@ export const makeGitManager = Effect.fn("makeGitManager")(function* () { |
| 731 | workingTree: details.workingTree, | 731 | workingTree: details.workingTree, |
| 732 | } satisfies GitStatusLocalResult; | 732 | } satisfies GitStatusLocalResult; |
| 733 | }); | 733 | }); |
| 734 | const localStatusResultCache = yield* Cache.makeWith({ | 734 | const localStatusResultCache = yield* Cache.makeWith(readLocalStatus, { |
| 735 | capacity: STATUS_RESULT_CACHE_CAPACITY, | 735 | capacity: STATUS_RESULT_CACHE_CAPACITY, |
| 736 | lookup: readLocalStatus, | ||
| 737 | timeToLive: (exit) => (Exit.isSuccess(exit) ? STATUS_RESULT_CACHE_TTL : Duration.zero), | 736 | timeToLive: (exit) => (Exit.isSuccess(exit) ? STATUS_RESULT_CACHE_TTL : Duration.zero), |
| 738 | }); | 737 | }); |
| 739 | const invalidateLocalStatusResultCache = (cwd: string) => | 738 | const invalidateLocalStatusResultCache = (cwd: string) => |
| ... | @@ -764,9 +763,8 @@ export const makeGitManager = Effect.fn("makeGitManager")(function* () { | ... | @@ -764,9 +763,8 @@ export const makeGitManager = Effect.fn("makeGitManager")(function* () { |
| 764 | pr, | 763 | pr, |
| 765 | } satisfies GitStatusRemoteResult; | 764 | } satisfies GitStatusRemoteResult; |
| 766 | }); | 765 | }); |
| 767 | const remoteStatusResultCache = yield* Cache.makeWith({ | 766 | const remoteStatusResultCache = yield* Cache.makeWith(readRemoteStatus, { |
| 768 | capacity: STATUS_RESULT_CACHE_CAPACITY, | 767 | capacity: STATUS_RESULT_CACHE_CAPACITY, |
| 769 | lookup: readRemoteStatus, | ||
| 770 | timeToLive: (exit) => (Exit.isSuccess(exit) ? STATUS_RESULT_CACHE_TTL : Duration.zero), | 768 | timeToLive: (exit) => (Exit.isSuccess(exit) ? STATUS_RESULT_CACHE_TTL : Duration.zero), |
| 771 | }); | 769 | }); |
| 772 | const invalidateRemoteStatusResultCache = (cwd: string) => | 770 | const invalidateRemoteStatusResultCache = (cwd: string) => |
apps/server/src/git/Layers/RoutingTextGeneration.ts+3-3| ... | @@ -9,7 +9,7 @@ | ... | @@ -9,7 +9,7 @@ |
| 9 | * | 9 | * |
| 10 | * @module RoutingTextGeneration | 10 | * @module RoutingTextGeneration |
| 11 | */ | 11 | */ |
| 12 | import { Effect, Layer, ServiceMap } from "effect"; | 12 | import { Effect, Layer, Context } from "effect"; |
| 13 | 13 | ||
| 14 | import { | 14 | import { |
| 15 | TextGeneration, | 15 | TextGeneration, |
| ... | @@ -23,11 +23,11 @@ import { ClaudeTextGenerationLive } from "./ClaudeTextGeneration.ts"; | ... | @@ -23,11 +23,11 @@ import { ClaudeTextGenerationLive } from "./ClaudeTextGeneration.ts"; |
| 23 | // Internal service tags so both concrete layers can coexist. | 23 | // Internal service tags so both concrete layers can coexist. |
| 24 | // --------------------------------------------------------------------------- | 24 | // --------------------------------------------------------------------------- |
| 25 | 25 | ||
| 26 | class CodexTextGen extends ServiceMap.Service<CodexTextGen, TextGenerationShape>()( | 26 | class CodexTextGen extends Context.Service<CodexTextGen, TextGenerationShape>()( |
| 27 | "t3/git/Layers/RoutingTextGeneration/CodexTextGen", | 27 | "t3/git/Layers/RoutingTextGeneration/CodexTextGen", |
| 28 | ) {} | 28 | ) {} |
| 29 | 29 | ||
| 30 | class ClaudeTextGen extends ServiceMap.Service<ClaudeTextGen, TextGenerationShape>()( | 30 | class ClaudeTextGen extends Context.Service<ClaudeTextGen, TextGenerationShape>()( |
| 31 | "t3/git/Layers/RoutingTextGeneration/ClaudeTextGen", | 31 | "t3/git/Layers/RoutingTextGeneration/ClaudeTextGen", |
| 32 | ) {} | 32 | ) {} |
| 33 | 33 |
apps/server/src/git/Services/GitCore.ts+2-4| ... | @@ -6,7 +6,7 @@ | ... | @@ -6,7 +6,7 @@ |
| 6 | * | 6 | * |
| 7 | * @module GitCore | 7 | * @module GitCore |
| 8 | */ | 8 | */ |
| 9 | import { ServiceMap } from "effect"; | 9 | import { Context } from "effect"; |
| 10 | import type { Effect } from "effect"; | 10 | import type { Effect } from "effect"; |
| 11 | import type { | 11 | import type { |
| 12 | GitCheckoutInput, | 12 | GitCheckoutInput, |
| ... | @@ -310,6 +310,4 @@ export interface GitCoreShape { | ... | @@ -310,6 +310,4 @@ export interface GitCoreShape { |
| 310 | /** | 310 | /** |
| 311 | * GitCore - Service tag for low-level Git repository operations. | 311 | * GitCore - Service tag for low-level Git repository operations. |
| 312 | */ | 312 | */ |
| 313 | export class GitCore extends ServiceMap.Service<GitCore, GitCoreShape>()( | 313 | export class GitCore extends Context.Service<GitCore, GitCoreShape>()("t3/git/Services/GitCore") {} |
| 314 | "t3/git/Services/GitCore", | ||
| 315 | ) {} |
apps/server/src/git/Services/GitHubCli.ts+2-2| ... | @@ -5,7 +5,7 @@ | ... | @@ -5,7 +5,7 @@ |
| 5 | * | 5 | * |
| 6 | * @module GitHubCli | 6 | * @module GitHubCli |
| 7 | */ | 7 | */ |
| 8 | import { ServiceMap } from "effect"; | 8 | import { Context } from "effect"; |
| 9 | import type { Effect } from "effect"; | 9 | import type { Effect } from "effect"; |
| 10 | 10 | ||
| 11 | import type { ProcessRunResult } from "../../processRunner"; | 11 | import type { ProcessRunResult } from "../../processRunner"; |
| ... | @@ -98,6 +98,6 @@ export interface GitHubCliShape { | ... | @@ -98,6 +98,6 @@ export interface GitHubCliShape { |
| 98 | /** | 98 | /** |
| 99 | * GitHubCli - Service tag for GitHub CLI process execution. | 99 | * GitHubCli - Service tag for GitHub CLI process execution. |
| 100 | */ | 100 | */ |
| 101 | export class GitHubCli extends ServiceMap.Service<GitHubCli, GitHubCliShape>()( | 101 | export class GitHubCli extends Context.Service<GitHubCli, GitHubCliShape>()( |
| 102 | "t3/git/Services/GitHubCli", | 102 | "t3/git/Services/GitHubCli", |
| 103 | ) {} | 103 | ) {} |
apps/server/src/git/Services/GitManager.ts+2-2| ... | @@ -19,7 +19,7 @@ import { | ... | @@ -19,7 +19,7 @@ import { |
| 19 | GitStatusInput, | 19 | GitStatusInput, |
| 20 | GitStatusResult, | 20 | GitStatusResult, |
| 21 | } from "@t3tools/contracts"; | 21 | } from "@t3tools/contracts"; |
| 22 | import { ServiceMap } from "effect"; | 22 | import { Context } from "effect"; |
| 23 | import type { Effect } from "effect"; | 23 | import type { Effect } from "effect"; |
| 24 | import type { GitManagerServiceError } from "@t3tools/contracts"; | 24 | import type { GitManagerServiceError } from "@t3tools/contracts"; |
| 25 | 25 | ||
| ... | @@ -99,6 +99,6 @@ export interface GitManagerShape { | ... | @@ -99,6 +99,6 @@ export interface GitManagerShape { |
| 99 | /** | 99 | /** |
| 100 | * GitManager - Service tag for stacked Git workflow orchestration. | 100 | * GitManager - Service tag for stacked Git workflow orchestration. |
| 101 | */ | 101 | */ |
| 102 | export class GitManager extends ServiceMap.Service<GitManager, GitManagerShape>()( | 102 | export class GitManager extends Context.Service<GitManager, GitManagerShape>()( |
| 103 | "t3/git/Services/GitManager", | 103 | "t3/git/Services/GitManager", |
| 104 | ) {} | 104 | ) {} |
apps/server/src/git/Services/GitStatusBroadcaster.ts+2-2| ... | @@ -1,4 +1,4 @@ | ... | @@ -1,4 +1,4 @@ |
| 1 | import { ServiceMap } from "effect"; | 1 | import { Context } from "effect"; |
| 2 | import type { Effect, Stream } from "effect"; | 2 | import type { Effect, Stream } from "effect"; |
| 3 | import type { | 3 | import type { |
| 4 | GitManagerServiceError, | 4 | GitManagerServiceError, |
| ... | @@ -21,7 +21,7 @@ export interface GitStatusBroadcasterShape { | ... | @@ -21,7 +21,7 @@ export interface GitStatusBroadcasterShape { |
| 21 | ) => Stream.Stream<GitStatusStreamEvent, GitManagerServiceError>; | 21 | ) => Stream.Stream<GitStatusStreamEvent, GitManagerServiceError>; |
| 22 | } | 22 | } |
| 23 | 23 | ||
| 24 | export class GitStatusBroadcaster extends ServiceMap.Service< | 24 | export class GitStatusBroadcaster extends Context.Service< |
| 25 | GitStatusBroadcaster, | 25 | GitStatusBroadcaster, |
| 26 | GitStatusBroadcasterShape | 26 | GitStatusBroadcasterShape |
| 27 | >()("t3/git/Services/GitStatusBroadcaster") {} | 27 | >()("t3/git/Services/GitStatusBroadcaster") {} |
apps/server/src/git/Services/TextGeneration.ts+2-2| ... | @@ -6,7 +6,7 @@ | ... | @@ -6,7 +6,7 @@ |
| 6 | * | 6 | * |
| 7 | * @module TextGeneration | 7 | * @module TextGeneration |
| 8 | */ | 8 | */ |
| 9 | import { ServiceMap } from "effect"; | 9 | import { Context } from "effect"; |
| 10 | import type { Effect } from "effect"; | 10 | import type { Effect } from "effect"; |
| 11 | import type { ChatAttachment, ModelSelection } from "@t3tools/contracts"; | 11 | import type { ChatAttachment, ModelSelection } from "@t3tools/contracts"; |
| 12 | 12 | ||
| ... | @@ -118,6 +118,6 @@ export interface TextGenerationShape { | ... | @@ -118,6 +118,6 @@ export interface TextGenerationShape { |
| 118 | /** | 118 | /** |
| 119 | * TextGeneration - Service tag for commit and PR text generation. | 119 | * TextGeneration - Service tag for commit and PR text generation. |
| 120 | */ | 120 | */ |
| 121 | export class TextGeneration extends ServiceMap.Service<TextGeneration, TextGenerationShape>()( | 121 | export class TextGeneration extends Context.Service<TextGeneration, TextGenerationShape>()( |
| 122 | "t3/git/Services/TextGeneration", | 122 | "t3/git/Services/TextGeneration", |
| 123 | ) {} | 123 | ) {} |
apps/server/src/keybindings.ts+2-2| ... | @@ -39,7 +39,7 @@ import { | ... | @@ -39,7 +39,7 @@ import { |
| 39 | SchemaIssue, | 39 | SchemaIssue, |
| 40 | SchemaTransformation, | 40 | SchemaTransformation, |
| 41 | Ref, | 41 | Ref, |
| 42 | ServiceMap, | 42 | Context, |
| 43 | Scope, | 43 | Scope, |
| 44 | Stream, | 44 | Stream, |
| 45 | } from "effect"; | 45 | } from "effect"; |
| ... | @@ -521,7 +521,7 @@ export interface KeybindingsShape { | ... | @@ -521,7 +521,7 @@ export interface KeybindingsShape { |
| 521 | /** | 521 | /** |
| 522 | * Keybindings - Service tag for keybinding configuration operations. | 522 | * Keybindings - Service tag for keybinding configuration operations. |
| 523 | */ | 523 | */ |
| 524 | export class Keybindings extends ServiceMap.Service<Keybindings, KeybindingsShape>()( | 524 | export class Keybindings extends Context.Service<Keybindings, KeybindingsShape>()( |
| 525 | "t3/keybindings", | 525 | "t3/keybindings", |
| 526 | ) {} | 526 | ) {} |
| 527 | 527 |
apps/server/src/observability/Services/BrowserTraceCollector.ts+2-2| ... | @@ -1,4 +1,4 @@ | ... | @@ -1,4 +1,4 @@ |
| 1 | import { ServiceMap } from "effect"; | 1 | import { Context } from "effect"; |
| 2 | import type { Effect } from "effect"; | 2 | import type { Effect } from "effect"; |
| 3 | 3 | ||
| 4 | import type { TraceRecord } from "../TraceRecord.ts"; | 4 | import type { TraceRecord } from "../TraceRecord.ts"; |
| ... | @@ -7,7 +7,7 @@ export interface BrowserTraceCollectorShape { | ... | @@ -7,7 +7,7 @@ export interface BrowserTraceCollectorShape { |
| 7 | readonly record: (records: ReadonlyArray<TraceRecord>) => Effect.Effect<void>; | 7 | readonly record: (records: ReadonlyArray<TraceRecord>) => Effect.Effect<void>; |
| 8 | } | 8 | } |
| 9 | 9 | ||
| 10 | export class BrowserTraceCollector extends ServiceMap.Service< | 10 | export class BrowserTraceCollector extends Context.Service< |
| 11 | BrowserTraceCollector, | 11 | BrowserTraceCollector, |
| 12 | BrowserTraceCollectorShape | 12 | BrowserTraceCollectorShape |
| 13 | >()("t3/observability/Services/BrowserTraceCollector") {} | 13 | >()("t3/observability/Services/BrowserTraceCollector") {} |
apps/server/src/open.ts+2-2| ... | @@ -11,7 +11,7 @@ import { accessSync, constants, statSync } from "node:fs"; | ... | @@ -11,7 +11,7 @@ import { accessSync, constants, statSync } from "node:fs"; |
| 11 | import { extname, join } from "node:path"; | 11 | import { extname, join } from "node:path"; |
| 12 | 12 | ||
| 13 | import { EDITORS, OpenError, type EditorId } from "@t3tools/contracts"; | 13 | import { EDITORS, OpenError, type EditorId } from "@t3tools/contracts"; |
| 14 | import { ServiceMap, Effect, Layer } from "effect"; | 14 | import { Context, Effect, Layer } from "effect"; |
| 15 | 15 | ||
| 16 | // ============================== | 16 | // ============================== |
| 17 | // Definitions | 17 | // Definitions |
| ... | @@ -247,7 +247,7 @@ export interface OpenShape { | ... | @@ -247,7 +247,7 @@ export interface OpenShape { |
| 247 | /** | 247 | /** |
| 248 | * Open - Service tag for browser/editor launch operations. | 248 | * Open - Service tag for browser/editor launch operations. |
| 249 | */ | 249 | */ |
| 250 | export class Open extends ServiceMap.Service<Open, OpenShape>()("t3/open") {} | 250 | export class Open extends Context.Service<Open, OpenShape>()("t3/open") {} |
| 251 | 251 | ||
| 252 | // ============================== | 252 | // ============================== |
| 253 | // Implementations | 253 | // Implementations |
apps/server/src/orchestration/Layers/CheckpointReactor.test.ts+118-120| ... | @@ -44,8 +44,8 @@ import { ServerConfig } from "../../config.ts"; | ... | @@ -44,8 +44,8 @@ import { ServerConfig } from "../../config.ts"; |
| 44 | import { WorkspaceEntriesLive } from "../../workspace/Layers/WorkspaceEntries.ts"; | 44 | import { WorkspaceEntriesLive } from "../../workspace/Layers/WorkspaceEntries.ts"; |
| 45 | import { WorkspacePathsLive } from "../../workspace/Layers/WorkspacePaths.ts"; | 45 | import { WorkspacePathsLive } from "../../workspace/Layers/WorkspacePaths.ts"; |
| 46 | 46 | ||
| 47 | const asProjectId = (value: string): ProjectId => ProjectId.makeUnsafe(value); | 47 | const asProjectId = (value: string): ProjectId => ProjectId.make(value); |
| 48 | const asTurnId = (value: string): TurnId => TurnId.makeUnsafe(value); | 48 | const asTurnId = (value: string): TurnId => TurnId.make(value); |
| 49 | 49 | ||
| 50 | type LegacyProviderRuntimeEvent = { | 50 | type LegacyProviderRuntimeEvent = { |
| 51 | readonly type: string; | 51 | readonly type: string; |
| ... | @@ -81,7 +81,7 @@ function createProviderServiceHarness( | ... | @@ -81,7 +81,7 @@ function createProviderServiceHarness( |
| 81 | provider: providerName, | 81 | provider: providerName, |
| 82 | status: "ready", | 82 | status: "ready", |
| 83 | runtimeMode: "full-access", | 83 | runtimeMode: "full-access", |
| 84 | threadId: ThreadId.makeUnsafe("thread-1"), | 84 | threadId: ThreadId.make("thread-1"), |
| 85 | cwd: sessionCwd, | 85 | cwd: sessionCwd, |
| 86 | createdAt: now, | 86 | createdAt: now, |
| 87 | updatedAt: now, | 87 | updatedAt: now, |
| ... | @@ -130,7 +130,7 @@ async function waitForThread( | ... | @@ -130,7 +130,7 @@ async function waitForThread( |
| 130 | activities: ReadonlyArray<{ kind: string }>; | 130 | activities: ReadonlyArray<{ kind: string }>; |
| 131 | }> => { | 131 | }> => { |
| 132 | const readModel = await Effect.runPromise(engine.getReadModel()); | 132 | const readModel = await Effect.runPromise(engine.getReadModel()); |
| 133 | const thread = readModel.threads.find((entry) => entry.id === ThreadId.makeUnsafe("thread-1")); | 133 | const thread = readModel.threads.find((entry) => entry.id === ThreadId.make("thread-1")); |
| 134 | if (thread && predicate(thread)) { | 134 | if (thread && predicate(thread)) { |
| 135 | return thread; | 135 | return thread; |
| 136 | } | 136 | } |
| ... | @@ -310,7 +310,7 @@ describe("CheckpointReactor", () => { | ... | @@ -310,7 +310,7 @@ describe("CheckpointReactor", () => { |
| 310 | await Effect.runPromise( | 310 | await Effect.runPromise( |
| 311 | engine.dispatch({ | 311 | engine.dispatch({ |
| 312 | type: "project.create", | 312 | type: "project.create", |
| 313 | commandId: CommandId.makeUnsafe("cmd-project-create"), | 313 | commandId: CommandId.make("cmd-project-create"), |
| 314 | projectId: asProjectId("project-1"), | 314 | projectId: asProjectId("project-1"), |
| 315 | title: "Test Project", | 315 | title: "Test Project", |
| 316 | workspaceRoot: options?.projectWorkspaceRoot ?? cwd, | 316 | workspaceRoot: options?.projectWorkspaceRoot ?? cwd, |
| ... | @@ -324,8 +324,8 @@ describe("CheckpointReactor", () => { | ... | @@ -324,8 +324,8 @@ describe("CheckpointReactor", () => { |
| 324 | await Effect.runPromise( | 324 | await Effect.runPromise( |
| 325 | engine.dispatch({ | 325 | engine.dispatch({ |
| 326 | type: "thread.create", | 326 | type: "thread.create", |
| 327 | commandId: CommandId.makeUnsafe("cmd-thread-create"), | 327 | commandId: CommandId.make("cmd-thread-create"), |
| 328 | threadId: ThreadId.makeUnsafe("thread-1"), | 328 | threadId: ThreadId.make("thread-1"), |
| 329 | projectId: asProjectId("project-1"), | 329 | projectId: asProjectId("project-1"), |
| 330 | title: "Thread", | 330 | title: "Thread", |
| 331 | modelSelection: { | 331 | modelSelection: { |
| ... | @@ -344,21 +344,21 @@ describe("CheckpointReactor", () => { | ... | @@ -344,21 +344,21 @@ describe("CheckpointReactor", () => { |
| 344 | await runtime.runPromise( | 344 | await runtime.runPromise( |
| 345 | checkpointStore.captureCheckpoint({ | 345 | checkpointStore.captureCheckpoint({ |
| 346 | cwd, | 346 | cwd, |
| 347 | checkpointRef: checkpointRefForThreadTurn(ThreadId.makeUnsafe("thread-1"), 0), | 347 | checkpointRef: checkpointRefForThreadTurn(ThreadId.make("thread-1"), 0), |
| 348 | }), | 348 | }), |
| 349 | ); | 349 | ); |
| 350 | fs.writeFileSync(path.join(cwd, "README.md"), "v2\n", "utf8"); | 350 | fs.writeFileSync(path.join(cwd, "README.md"), "v2\n", "utf8"); |
| 351 | await runtime.runPromise( | 351 | await runtime.runPromise( |
| 352 | checkpointStore.captureCheckpoint({ | 352 | checkpointStore.captureCheckpoint({ |
| 353 | cwd, | 353 | cwd, |
| 354 | checkpointRef: checkpointRefForThreadTurn(ThreadId.makeUnsafe("thread-1"), 1), | 354 | checkpointRef: checkpointRefForThreadTurn(ThreadId.make("thread-1"), 1), |
| 355 | }), | 355 | }), |
| 356 | ); | 356 | ); |
| 357 | fs.writeFileSync(path.join(cwd, "README.md"), "v3\n", "utf8"); | 357 | fs.writeFileSync(path.join(cwd, "README.md"), "v3\n", "utf8"); |
| 358 | await runtime.runPromise( | 358 | await runtime.runPromise( |
| 359 | checkpointStore.captureCheckpoint({ | 359 | checkpointStore.captureCheckpoint({ |
| 360 | cwd, | 360 | cwd, |
| 361 | checkpointRef: checkpointRefForThreadTurn(ThreadId.makeUnsafe("thread-1"), 2), | 361 | checkpointRef: checkpointRefForThreadTurn(ThreadId.make("thread-1"), 2), |
| 362 | }), | 362 | }), |
| 363 | ); | 363 | ); |
| 364 | } | 364 | } |
| ... | @@ -378,10 +378,10 @@ describe("CheckpointReactor", () => { | ... | @@ -378,10 +378,10 @@ describe("CheckpointReactor", () => { |
| 378 | await Effect.runPromise( | 378 | await Effect.runPromise( |
| 379 | harness.engine.dispatch({ | 379 | harness.engine.dispatch({ |
| 380 | type: "thread.session.set", | 380 | type: "thread.session.set", |
| 381 | commandId: CommandId.makeUnsafe("cmd-session-set-capture"), | 381 | commandId: CommandId.make("cmd-session-set-capture"), |
| 382 | threadId: ThreadId.makeUnsafe("thread-1"), | 382 | threadId: ThreadId.make("thread-1"), |
| 383 | session: { | 383 | session: { |
| 384 | threadId: ThreadId.makeUnsafe("thread-1"), | 384 | threadId: ThreadId.make("thread-1"), |
| 385 | status: "ready", | 385 | status: "ready", |
| 386 | providerName: "codex", | 386 | providerName: "codex", |
| 387 | runtimeMode: "approval-required", | 387 | runtimeMode: "approval-required", |
| ... | @@ -395,26 +395,26 @@ describe("CheckpointReactor", () => { | ... | @@ -395,26 +395,26 @@ describe("CheckpointReactor", () => { |
| 395 | 395 | ||
| 396 | harness.provider.emit({ | 396 | harness.provider.emit({ |
| 397 | type: "turn.started", | 397 | type: "turn.started", |
| 398 | eventId: EventId.makeUnsafe("evt-turn-started-1"), | 398 | eventId: EventId.make("evt-turn-started-1"), |
| 399 | provider: "codex", | 399 | provider: "codex", |
| 400 | 400 | ||
| 401 | createdAt: new Date().toISOString(), | 401 | createdAt: new Date().toISOString(), |
| 402 | threadId: ThreadId.makeUnsafe("thread-1"), | 402 | threadId: ThreadId.make("thread-1"), |
| 403 | turnId: asTurnId("turn-1"), | 403 | turnId: asTurnId("turn-1"), |
| 404 | }); | 404 | }); |
| 405 | await waitForGitRefExists( | 405 | await waitForGitRefExists( |
| 406 | harness.cwd, | 406 | harness.cwd, |
| 407 | checkpointRefForThreadTurn(ThreadId.makeUnsafe("thread-1"), 0), | 407 | checkpointRefForThreadTurn(ThreadId.make("thread-1"), 0), |
| 408 | ); | 408 | ); |
| 409 | 409 | ||
| 410 | fs.writeFileSync(path.join(harness.cwd, "README.md"), "v2\n", "utf8"); | 410 | fs.writeFileSync(path.join(harness.cwd, "README.md"), "v2\n", "utf8"); |
| 411 | harness.provider.emit({ | 411 | harness.provider.emit({ |
| 412 | type: "turn.completed", | 412 | type: "turn.completed", |
| 413 | eventId: EventId.makeUnsafe("evt-turn-completed-1"), | 413 | eventId: EventId.make("evt-turn-completed-1"), |
| 414 | provider: "codex", | 414 | provider: "codex", |
| 415 | 415 | ||
| 416 | createdAt: new Date().toISOString(), | 416 | createdAt: new Date().toISOString(), |
| 417 | threadId: ThreadId.makeUnsafe("thread-1"), | 417 | threadId: ThreadId.make("thread-1"), |
| 418 | turnId: asTurnId("turn-1"), | 418 | turnId: asTurnId("turn-1"), |
| 419 | payload: { state: "completed" }, | 419 | payload: { state: "completed" }, |
| 420 | }); | 420 | }); |
| ... | @@ -426,22 +426,22 @@ describe("CheckpointReactor", () => { | ... | @@ -426,22 +426,22 @@ describe("CheckpointReactor", () => { |
| 426 | ); | 426 | ); |
| 427 | expect(thread.checkpoints[0]?.checkpointTurnCount).toBe(1); | 427 | expect(thread.checkpoints[0]?.checkpointTurnCount).toBe(1); |
| 428 | expect( | 428 | expect( |
| 429 | gitRefExists(harness.cwd, checkpointRefForThreadTurn(ThreadId.makeUnsafe("thread-1"), 0)), | 429 | gitRefExists(harness.cwd, checkpointRefForThreadTurn(ThreadId.make("thread-1"), 0)), |
| 430 | ).toBe(true); | 430 | ).toBe(true); |
| 431 | expect( | 431 | expect( |
| 432 | gitRefExists(harness.cwd, checkpointRefForThreadTurn(ThreadId.makeUnsafe("thread-1"), 1)), | 432 | gitRefExists(harness.cwd, checkpointRefForThreadTurn(ThreadId.make("thread-1"), 1)), |
| 433 | ).toBe(true); | 433 | ).toBe(true); |
| 434 | expect( | 434 | expect( |
| 435 | gitShowFileAtRef( | 435 | gitShowFileAtRef( |
| 436 | harness.cwd, | 436 | harness.cwd, |
| 437 | checkpointRefForThreadTurn(ThreadId.makeUnsafe("thread-1"), 0), | 437 | checkpointRefForThreadTurn(ThreadId.make("thread-1"), 0), |
| 438 | "README.md", | 438 | "README.md", |
| 439 | ), | 439 | ), |
| 440 | ).toBe("v1\n"); | 440 | ).toBe("v1\n"); |
| 441 | expect( | 441 | expect( |
| 442 | gitShowFileAtRef( | 442 | gitShowFileAtRef( |
| 443 | harness.cwd, | 443 | harness.cwd, |
| 444 | checkpointRefForThreadTurn(ThreadId.makeUnsafe("thread-1"), 1), | 444 | checkpointRefForThreadTurn(ThreadId.make("thread-1"), 1), |
| 445 | "README.md", | 445 | "README.md", |
| 446 | ), | 446 | ), |
| 447 | ).toBe("v2\n"); | 447 | ).toBe("v2\n"); |
| ... | @@ -456,10 +456,10 @@ describe("CheckpointReactor", () => { | ... | @@ -456,10 +456,10 @@ describe("CheckpointReactor", () => { |
| 456 | 456 | ||
| 457 | harness.provider.emit({ | 457 | harness.provider.emit({ |
| 458 | type: "turn.completed", | 458 | type: "turn.completed", |
| 459 | eventId: EventId.makeUnsafe("evt-turn-completed-refresh-local-status"), | 459 | eventId: EventId.make("evt-turn-completed-refresh-local-status"), |
| 460 | provider: "codex", | 460 | provider: "codex", |
| 461 | createdAt: new Date().toISOString(), | 461 | createdAt: new Date().toISOString(), |
| 462 | threadId: ThreadId.makeUnsafe("thread-1"), | 462 | threadId: ThreadId.make("thread-1"), |
| 463 | turnId: asTurnId("turn-refresh-local-status"), | 463 | turnId: asTurnId("turn-refresh-local-status"), |
| 464 | payload: { state: "completed" }, | 464 | payload: { state: "completed" }, |
| 465 | }); | 465 | }); |
| ... | @@ -476,10 +476,10 @@ describe("CheckpointReactor", () => { | ... | @@ -476,10 +476,10 @@ describe("CheckpointReactor", () => { |
| 476 | await Effect.runPromise( | 476 | await Effect.runPromise( |
| 477 | harness.engine.dispatch({ | 477 | harness.engine.dispatch({ |
| 478 | type: "thread.session.set", | 478 | type: "thread.session.set", |
| 479 | commandId: CommandId.makeUnsafe("cmd-session-set-primary-running"), | 479 | commandId: CommandId.make("cmd-session-set-primary-running"), |
| 480 | threadId: ThreadId.makeUnsafe("thread-1"), | 480 | threadId: ThreadId.make("thread-1"), |
| 481 | session: { | 481 | session: { |
| 482 | threadId: ThreadId.makeUnsafe("thread-1"), | 482 | threadId: ThreadId.make("thread-1"), |
| 483 | status: "running", | 483 | status: "running", |
| 484 | providerName: "codex", | 484 | providerName: "codex", |
| 485 | runtimeMode: "approval-required", | 485 | runtimeMode: "approval-required", |
| ... | @@ -493,45 +493,43 @@ describe("CheckpointReactor", () => { | ... | @@ -493,45 +493,43 @@ describe("CheckpointReactor", () => { |
| 493 | 493 | ||
| 494 | harness.provider.emit({ | 494 | harness.provider.emit({ |
| 495 | type: "turn.started", | 495 | type: "turn.started", |
| 496 | eventId: EventId.makeUnsafe("evt-turn-started-main"), | 496 | eventId: EventId.make("evt-turn-started-main"), |
| 497 | provider: "codex", | 497 | provider: "codex", |
| 498 | 498 | ||
| 499 | createdAt: new Date().toISOString(), | 499 | createdAt: new Date().toISOString(), |
| 500 | threadId: ThreadId.makeUnsafe("thread-1"), | 500 | threadId: ThreadId.make("thread-1"), |
| 501 | turnId: asTurnId("turn-main"), | 501 | turnId: asTurnId("turn-main"), |
| 502 | }); | 502 | }); |
| 503 | await waitForGitRefExists( | 503 | await waitForGitRefExists( |
| 504 | harness.cwd, | 504 | harness.cwd, |
| 505 | checkpointRefForThreadTurn(ThreadId.makeUnsafe("thread-1"), 0), | 505 | checkpointRefForThreadTurn(ThreadId.make("thread-1"), 0), |
| 506 | ); | 506 | ); |
| 507 | 507 | ||
| 508 | fs.writeFileSync(path.join(harness.cwd, "README.md"), "v2\n", "utf8"); | 508 | fs.writeFileSync(path.join(harness.cwd, "README.md"), "v2\n", "utf8"); |
| 509 | 509 | ||
| 510 | harness.provider.emit({ | 510 | harness.provider.emit({ |
| 511 | type: "turn.completed", | 511 | type: "turn.completed", |
| 512 | eventId: EventId.makeUnsafe("evt-turn-completed-aux"), | 512 | eventId: EventId.make("evt-turn-completed-aux"), |
| 513 | provider: "codex", | 513 | provider: "codex", |
| 514 | 514 | ||
| 515 | createdAt: new Date().toISOString(), | 515 | createdAt: new Date().toISOString(), |
| 516 | threadId: ThreadId.makeUnsafe("thread-1"), | 516 | threadId: ThreadId.make("thread-1"), |
| 517 | turnId: asTurnId("turn-aux"), | 517 | turnId: asTurnId("turn-aux"), |
| 518 | payload: { state: "completed" }, | 518 | payload: { state: "completed" }, |
| 519 | }); | 519 | }); |
| 520 | 520 | ||
| 521 | await harness.drain(); | 521 | await harness.drain(); |
| 522 | const midReadModel = await Effect.runPromise(harness.engine.getReadModel()); | 522 | const midReadModel = await Effect.runPromise(harness.engine.getReadModel()); |
| 523 | const midThread = midReadModel.threads.find( | 523 | const midThread = midReadModel.threads.find((entry) => entry.id === ThreadId.make("thread-1")); |
| 524 | (entry) => entry.id === ThreadId.makeUnsafe("thread-1"), | ||
| 525 | ); | ||
| 526 | expect(midThread?.checkpoints).toHaveLength(0); | 524 | expect(midThread?.checkpoints).toHaveLength(0); |
| 527 | 525 | ||
| 528 | harness.provider.emit({ | 526 | harness.provider.emit({ |
| 529 | type: "turn.completed", | 527 | type: "turn.completed", |
| 530 | eventId: EventId.makeUnsafe("evt-turn-completed-main"), | 528 | eventId: EventId.make("evt-turn-completed-main"), |
| 531 | provider: "codex", | 529 | provider: "codex", |
| 532 | 530 | ||
| 533 | createdAt: new Date().toISOString(), | 531 | createdAt: new Date().toISOString(), |
| 534 | threadId: ThreadId.makeUnsafe("thread-1"), | 532 | threadId: ThreadId.make("thread-1"), |
| 535 | turnId: asTurnId("turn-main"), | 533 | turnId: asTurnId("turn-main"), |
| 536 | payload: { state: "completed" }, | 534 | payload: { state: "completed" }, |
| 537 | }); | 535 | }); |
| ... | @@ -553,10 +551,10 @@ describe("CheckpointReactor", () => { | ... | @@ -553,10 +551,10 @@ describe("CheckpointReactor", () => { |
| 553 | await Effect.runPromise( | 551 | await Effect.runPromise( |
| 554 | harness.engine.dispatch({ | 552 | harness.engine.dispatch({ |
| 555 | type: "thread.session.set", | 553 | type: "thread.session.set", |
| 556 | commandId: CommandId.makeUnsafe("cmd-session-set-capture-claude"), | 554 | commandId: CommandId.make("cmd-session-set-capture-claude"), |
| 557 | threadId: ThreadId.makeUnsafe("thread-1"), | 555 | threadId: ThreadId.make("thread-1"), |
| 558 | session: { | 556 | session: { |
| 559 | threadId: ThreadId.makeUnsafe("thread-1"), | 557 | threadId: ThreadId.make("thread-1"), |
| 560 | status: "ready", | 558 | status: "ready", |
| 561 | providerName: "claudeAgent", | 559 | providerName: "claudeAgent", |
| 562 | runtimeMode: "approval-required", | 560 | runtimeMode: "approval-required", |
| ... | @@ -570,24 +568,24 @@ describe("CheckpointReactor", () => { | ... | @@ -570,24 +568,24 @@ describe("CheckpointReactor", () => { |
| 570 | 568 | ||
| 571 | harness.provider.emit({ | 569 | harness.provider.emit({ |
| 572 | type: "turn.started", | 570 | type: "turn.started", |
| 573 | eventId: EventId.makeUnsafe("evt-turn-started-claude-1"), | 571 | eventId: EventId.make("evt-turn-started-claude-1"), |
| 574 | provider: "claudeAgent", | 572 | provider: "claudeAgent", |
| 575 | createdAt: new Date().toISOString(), | 573 | createdAt: new Date().toISOString(), |
| 576 | threadId: ThreadId.makeUnsafe("thread-1"), | 574 | threadId: ThreadId.make("thread-1"), |
| 577 | turnId: asTurnId("turn-claude-1"), | 575 | turnId: asTurnId("turn-claude-1"), |
| 578 | }); | 576 | }); |
| 579 | await waitForGitRefExists( | 577 | await waitForGitRefExists( |
| 580 | harness.cwd, | 578 | harness.cwd, |
| 581 | checkpointRefForThreadTurn(ThreadId.makeUnsafe("thread-1"), 0), | 579 | checkpointRefForThreadTurn(ThreadId.make("thread-1"), 0), |
| 582 | ); | 580 | ); |
| 583 | 581 | ||
| 584 | fs.writeFileSync(path.join(harness.cwd, "README.md"), "v2\n", "utf8"); | 582 | fs.writeFileSync(path.join(harness.cwd, "README.md"), "v2\n", "utf8"); |
| 585 | harness.provider.emit({ | 583 | harness.provider.emit({ |
| 586 | type: "turn.completed", | 584 | type: "turn.completed", |
| 587 | eventId: EventId.makeUnsafe("evt-turn-completed-claude-1"), | 585 | eventId: EventId.make("evt-turn-completed-claude-1"), |
| 588 | provider: "claudeAgent", | 586 | provider: "claudeAgent", |
| 589 | createdAt: new Date().toISOString(), | 587 | createdAt: new Date().toISOString(), |
| 590 | threadId: ThreadId.makeUnsafe("thread-1"), | 588 | threadId: ThreadId.make("thread-1"), |
| 591 | turnId: asTurnId("turn-claude-1"), | 589 | turnId: asTurnId("turn-claude-1"), |
| 592 | payload: { state: "completed" }, | 590 | payload: { state: "completed" }, |
| 593 | }); | 591 | }); |
| ... | @@ -600,7 +598,7 @@ describe("CheckpointReactor", () => { | ... | @@ -600,7 +598,7 @@ describe("CheckpointReactor", () => { |
| 600 | 598 | ||
| 601 | expect(thread.checkpoints[0]?.checkpointTurnCount).toBe(1); | 599 | expect(thread.checkpoints[0]?.checkpointTurnCount).toBe(1); |
| 602 | expect( | 600 | expect( |
| 603 | gitRefExists(harness.cwd, checkpointRefForThreadTurn(ThreadId.makeUnsafe("thread-1"), 1)), | 601 | gitRefExists(harness.cwd, checkpointRefForThreadTurn(ThreadId.make("thread-1"), 1)), |
| 604 | ).toBe(true); | 602 | ).toBe(true); |
| 605 | }); | 603 | }); |
| 606 | 604 | ||
| ... | @@ -611,10 +609,10 @@ describe("CheckpointReactor", () => { | ... | @@ -611,10 +609,10 @@ describe("CheckpointReactor", () => { |
| 611 | await Effect.runPromise( | 609 | await Effect.runPromise( |
| 612 | harness.engine.dispatch({ | 610 | harness.engine.dispatch({ |
| 613 | type: "thread.session.set", | 611 | type: "thread.session.set", |
| 614 | commandId: CommandId.makeUnsafe("cmd-session-set-missing-baseline-diff"), | 612 | commandId: CommandId.make("cmd-session-set-missing-baseline-diff"), |
| 615 | threadId: ThreadId.makeUnsafe("thread-1"), | 613 | threadId: ThreadId.make("thread-1"), |
| 616 | session: { | 614 | session: { |
| 617 | threadId: ThreadId.makeUnsafe("thread-1"), | 615 | threadId: ThreadId.make("thread-1"), |
| 618 | status: "ready", | 616 | status: "ready", |
| 619 | providerName: "codex", | 617 | providerName: "codex", |
| 620 | runtimeMode: "approval-required", | 618 | runtimeMode: "approval-required", |
| ... | @@ -628,11 +626,11 @@ describe("CheckpointReactor", () => { | ... | @@ -628,11 +626,11 @@ describe("CheckpointReactor", () => { |
| 628 | 626 | ||
| 629 | harness.provider.emit({ | 627 | harness.provider.emit({ |
| 630 | type: "turn.completed", | 628 | type: "turn.completed", |
| 631 | eventId: EventId.makeUnsafe("evt-turn-completed-missing-baseline"), | 629 | eventId: EventId.make("evt-turn-completed-missing-baseline"), |
| 632 | provider: "codex", | 630 | provider: "codex", |
| 633 | 631 | ||
| 634 | createdAt: new Date().toISOString(), | 632 | createdAt: new Date().toISOString(), |
| 635 | threadId: ThreadId.makeUnsafe("thread-1"), | 633 | threadId: ThreadId.make("thread-1"), |
| 636 | turnId: asTurnId("turn-missing-baseline"), | 634 | turnId: asTurnId("turn-missing-baseline"), |
| 637 | payload: { state: "completed" }, | 635 | payload: { state: "completed" }, |
| 638 | }); | 636 | }); |
| ... | @@ -661,10 +659,10 @@ describe("CheckpointReactor", () => { | ... | @@ -661,10 +659,10 @@ describe("CheckpointReactor", () => { |
| 661 | await Effect.runPromise( | 659 | await Effect.runPromise( |
| 662 | harness.engine.dispatch({ | 660 | harness.engine.dispatch({ |
| 663 | type: "thread.turn.start", | 661 | type: "thread.turn.start", |
| 664 | commandId: CommandId.makeUnsafe("cmd-turn-start-for-baseline"), | 662 | commandId: CommandId.make("cmd-turn-start-for-baseline"), |
| 665 | threadId: ThreadId.makeUnsafe("thread-1"), | 663 | threadId: ThreadId.make("thread-1"), |
| 666 | message: { | 664 | message: { |
| 667 | messageId: MessageId.makeUnsafe("message-user-1"), | 665 | messageId: MessageId.make("message-user-1"), |
| 668 | role: "user", | 666 | role: "user", |
| 669 | text: "start turn", | 667 | text: "start turn", |
| 670 | attachments: [], | 668 | attachments: [], |
| ... | @@ -677,12 +675,12 @@ describe("CheckpointReactor", () => { | ... | @@ -677,12 +675,12 @@ describe("CheckpointReactor", () => { |
| 677 | 675 | ||
| 678 | await waitForGitRefExists( | 676 | await waitForGitRefExists( |
| 679 | harness.cwd, | 677 | harness.cwd, |
| 680 | checkpointRefForThreadTurn(ThreadId.makeUnsafe("thread-1"), 0), | 678 | checkpointRefForThreadTurn(ThreadId.make("thread-1"), 0), |
| 681 | ); | 679 | ); |
| 682 | expect( | 680 | expect( |
| 683 | gitShowFileAtRef( | 681 | gitShowFileAtRef( |
| 684 | harness.cwd, | 682 | harness.cwd, |
| 685 | checkpointRefForThreadTurn(ThreadId.makeUnsafe("thread-1"), 0), | 683 | checkpointRefForThreadTurn(ThreadId.make("thread-1"), 0), |
| 686 | "README.md", | 684 | "README.md", |
| 687 | ), | 685 | ), |
| 688 | ).toBe("v1\n"); | 686 | ).toBe("v1\n"); |
| ... | @@ -699,10 +697,10 @@ describe("CheckpointReactor", () => { | ... | @@ -699,10 +697,10 @@ describe("CheckpointReactor", () => { |
| 699 | await Effect.runPromise( | 697 | await Effect.runPromise( |
| 700 | harness.engine.dispatch({ | 698 | harness.engine.dispatch({ |
| 701 | type: "thread.session.set", | 699 | type: "thread.session.set", |
| 702 | commandId: CommandId.makeUnsafe("cmd-session-set-missing-provider-cwd"), | 700 | commandId: CommandId.make("cmd-session-set-missing-provider-cwd"), |
| 703 | threadId: ThreadId.makeUnsafe("thread-1"), | 701 | threadId: ThreadId.make("thread-1"), |
| 704 | session: { | 702 | session: { |
| 705 | threadId: ThreadId.makeUnsafe("thread-1"), | 703 | threadId: ThreadId.make("thread-1"), |
| 706 | status: "running", | 704 | status: "running", |
| 707 | providerName: "codex", | 705 | providerName: "codex", |
| 708 | runtimeMode: "approval-required", | 706 | runtimeMode: "approval-required", |
| ... | @@ -717,23 +715,23 @@ describe("CheckpointReactor", () => { | ... | @@ -717,23 +715,23 @@ describe("CheckpointReactor", () => { |
| 717 | fs.writeFileSync(path.join(harness.cwd, "README.md"), "v2\n", "utf8"); | 715 | fs.writeFileSync(path.join(harness.cwd, "README.md"), "v2\n", "utf8"); |
| 718 | harness.provider.emit({ | 716 | harness.provider.emit({ |
| 719 | type: "turn.completed", | 717 | type: "turn.completed", |
| 720 | eventId: EventId.makeUnsafe("evt-turn-completed-missing-provider-cwd"), | 718 | eventId: EventId.make("evt-turn-completed-missing-provider-cwd"), |
| 721 | provider: "codex", | 719 | provider: "codex", |
| 722 | 720 | ||
| 723 | createdAt: new Date().toISOString(), | 721 | createdAt: new Date().toISOString(), |
| 724 | threadId: ThreadId.makeUnsafe("thread-1"), | 722 | threadId: ThreadId.make("thread-1"), |
| 725 | turnId: asTurnId("turn-missing-cwd"), | 723 | turnId: asTurnId("turn-missing-cwd"), |
| 726 | payload: { state: "completed" }, | 724 | payload: { state: "completed" }, |
| 727 | }); | 725 | }); |
| 728 | 726 | ||
| 729 | await waitForEvent(harness.engine, (event) => event.type === "thread.turn-diff-completed"); | 727 | await waitForEvent(harness.engine, (event) => event.type === "thread.turn-diff-completed"); |
| 730 | expect( | 728 | expect( |
| 731 | gitRefExists(harness.cwd, checkpointRefForThreadTurn(ThreadId.makeUnsafe("thread-1"), 1)), | 729 | gitRefExists(harness.cwd, checkpointRefForThreadTurn(ThreadId.make("thread-1"), 1)), |
| 732 | ).toBe(true); | 730 | ).toBe(true); |
| 733 | expect( | 731 | expect( |
| 734 | gitShowFileAtRef( | 732 | gitShowFileAtRef( |
| 735 | harness.cwd, | 733 | harness.cwd, |
| 736 | checkpointRefForThreadTurn(ThreadId.makeUnsafe("thread-1"), 1), | 734 | checkpointRefForThreadTurn(ThreadId.make("thread-1"), 1), |
| 737 | "README.md", | 735 | "README.md", |
| 738 | ), | 736 | ), |
| 739 | ).toBe("v2\n"); | 737 | ).toBe("v2\n"); |
| ... | @@ -746,10 +744,10 @@ describe("CheckpointReactor", () => { | ... | @@ -746,10 +744,10 @@ describe("CheckpointReactor", () => { |
| 746 | await Effect.runPromise( | 744 | await Effect.runPromise( |
| 747 | harness.engine.dispatch({ | 745 | harness.engine.dispatch({ |
| 748 | type: "thread.session.set", | 746 | type: "thread.session.set", |
| 749 | commandId: CommandId.makeUnsafe("cmd-session-set-checkpoint-captured"), | 747 | commandId: CommandId.make("cmd-session-set-checkpoint-captured"), |
| 750 | threadId: ThreadId.makeUnsafe("thread-1"), | 748 | threadId: ThreadId.make("thread-1"), |
| 751 | session: { | 749 | session: { |
| 752 | threadId: ThreadId.makeUnsafe("thread-1"), | 750 | threadId: ThreadId.make("thread-1"), |
| 753 | status: "ready", | 751 | status: "ready", |
| 754 | providerName: "codex", | 752 | providerName: "codex", |
| 755 | runtimeMode: "approval-required", | 753 | runtimeMode: "approval-required", |
| ... | @@ -763,11 +761,11 @@ describe("CheckpointReactor", () => { | ... | @@ -763,11 +761,11 @@ describe("CheckpointReactor", () => { |
| 763 | 761 | ||
| 764 | harness.provider.emit({ | 762 | harness.provider.emit({ |
| 765 | type: "checkpoint.captured", | 763 | type: "checkpoint.captured", |
| 766 | eventId: EventId.makeUnsafe("evt-checkpoint-captured-3"), | 764 | eventId: EventId.make("evt-checkpoint-captured-3"), |
| 767 | provider: "codex", | 765 | provider: "codex", |
| 768 | 766 | ||
| 769 | createdAt: new Date().toISOString(), | 767 | createdAt: new Date().toISOString(), |
| 770 | threadId: ThreadId.makeUnsafe("thread-1"), | 768 | threadId: ThreadId.make("thread-1"), |
| 771 | turnId: asTurnId("turn-3"), | 769 | turnId: asTurnId("turn-3"), |
| 772 | turnCount: 3, | 770 | turnCount: 3, |
| 773 | status: "completed", | 771 | status: "completed", |
| ... | @@ -775,7 +773,7 @@ describe("CheckpointReactor", () => { | ... | @@ -775,7 +773,7 @@ describe("CheckpointReactor", () => { |
| 775 | 773 | ||
| 776 | await harness.drain(); | 774 | await harness.drain(); |
| 777 | const readModel = await Effect.runPromise(harness.engine.getReadModel()); | 775 | const readModel = await Effect.runPromise(harness.engine.getReadModel()); |
| 778 | const thread = readModel.threads.find((entry) => entry.id === ThreadId.makeUnsafe("thread-1")); | 776 | const thread = readModel.threads.find((entry) => entry.id === ThreadId.make("thread-1")); |
| 779 | expect(thread?.checkpoints.some((checkpoint) => checkpoint.checkpointTurnCount === 3)).toBe( | 777 | expect(thread?.checkpoints.some((checkpoint) => checkpoint.checkpointTurnCount === 3)).toBe( |
| 780 | false, | 778 | false, |
| 781 | ); | 779 | ); |
| ... | @@ -796,10 +794,10 @@ describe("CheckpointReactor", () => { | ... | @@ -796,10 +794,10 @@ describe("CheckpointReactor", () => { |
| 796 | await Effect.runPromise( | 794 | await Effect.runPromise( |
| 797 | harness.engine.dispatch({ | 795 | harness.engine.dispatch({ |
| 798 | type: "thread.session.set", | 796 | type: "thread.session.set", |
| 799 | commandId: CommandId.makeUnsafe("cmd-session-set-non-repo-runtime"), | 797 | commandId: CommandId.make("cmd-session-set-non-repo-runtime"), |
| 800 | threadId: ThreadId.makeUnsafe("thread-1"), | 798 | threadId: ThreadId.make("thread-1"), |
| 801 | session: { | 799 | session: { |
| 802 | threadId: ThreadId.makeUnsafe("thread-1"), | 800 | threadId: ThreadId.make("thread-1"), |
| 803 | status: "ready", | 801 | status: "ready", |
| 804 | providerName: "codex", | 802 | providerName: "codex", |
| 805 | runtimeMode: "approval-required", | 803 | runtimeMode: "approval-required", |
| ... | @@ -813,31 +811,31 @@ describe("CheckpointReactor", () => { | ... | @@ -813,31 +811,31 @@ describe("CheckpointReactor", () => { |
| 813 | 811 | ||
| 814 | harness.provider.emit({ | 812 | harness.provider.emit({ |
| 815 | type: "turn.completed", | 813 | type: "turn.completed", |
| 816 | eventId: EventId.makeUnsafe("evt-runtime-capture-failure"), | 814 | eventId: EventId.make("evt-runtime-capture-failure"), |
| 817 | provider: "codex", | 815 | provider: "codex", |
| 818 | 816 | ||
| 819 | createdAt: new Date().toISOString(), | 817 | createdAt: new Date().toISOString(), |
| 820 | threadId: ThreadId.makeUnsafe("thread-1"), | 818 | threadId: ThreadId.make("thread-1"), |
| 821 | turnId: asTurnId("turn-runtime-failure"), | 819 | turnId: asTurnId("turn-runtime-failure"), |
| 822 | payload: { state: "completed" }, | 820 | payload: { state: "completed" }, |
| 823 | }); | 821 | }); |
| 824 | 822 | ||
| 825 | harness.provider.emit({ | 823 | harness.provider.emit({ |
| 826 | type: "turn.started", | 824 | type: "turn.started", |
| 827 | eventId: EventId.makeUnsafe("evt-turn-started-after-runtime-failure"), | 825 | eventId: EventId.make("evt-turn-started-after-runtime-failure"), |
| 828 | provider: "codex", | 826 | provider: "codex", |
| 829 | 827 | ||
| 830 | createdAt: new Date().toISOString(), | 828 | createdAt: new Date().toISOString(), |
| 831 | threadId: ThreadId.makeUnsafe("thread-1"), | 829 | threadId: ThreadId.make("thread-1"), |
| 832 | turnId: asTurnId("turn-after-runtime-failure"), | 830 | turnId: asTurnId("turn-after-runtime-failure"), |
| 833 | }); | 831 | }); |
| 834 | 832 | ||
| 835 | await waitForGitRefExists( | 833 | await waitForGitRefExists( |
| 836 | harness.cwd, | 834 | harness.cwd, |
| 837 | checkpointRefForThreadTurn(ThreadId.makeUnsafe("thread-1"), 0), | 835 | checkpointRefForThreadTurn(ThreadId.make("thread-1"), 0), |
| 838 | ); | 836 | ); |
| 839 | expect( | 837 | expect( |
| 840 | gitRefExists(harness.cwd, checkpointRefForThreadTurn(ThreadId.makeUnsafe("thread-1"), 0)), | 838 | gitRefExists(harness.cwd, checkpointRefForThreadTurn(ThreadId.make("thread-1"), 0)), |
| 841 | ).toBe(true); | 839 | ).toBe(true); |
| 842 | }); | 840 | }); |
| 843 | 841 | ||
| ... | @@ -848,10 +846,10 @@ describe("CheckpointReactor", () => { | ... | @@ -848,10 +846,10 @@ describe("CheckpointReactor", () => { |
| 848 | await Effect.runPromise( | 846 | await Effect.runPromise( |
| 849 | harness.engine.dispatch({ | 847 | harness.engine.dispatch({ |
| 850 | type: "thread.session.set", | 848 | type: "thread.session.set", |
| 851 | commandId: CommandId.makeUnsafe("cmd-session-set"), | 849 | commandId: CommandId.make("cmd-session-set"), |
| 852 | threadId: ThreadId.makeUnsafe("thread-1"), | 850 | threadId: ThreadId.make("thread-1"), |
| 853 | session: { | 851 | session: { |
| 854 | threadId: ThreadId.makeUnsafe("thread-1"), | 852 | threadId: ThreadId.make("thread-1"), |
| 855 | status: "ready", | 853 | status: "ready", |
| 856 | providerName: "codex", | 854 | providerName: "codex", |
| 857 | runtimeMode: "approval-required", | 855 | runtimeMode: "approval-required", |
| ... | @@ -866,11 +864,11 @@ describe("CheckpointReactor", () => { | ... | @@ -866,11 +864,11 @@ describe("CheckpointReactor", () => { |
| 866 | await Effect.runPromise( | 864 | await Effect.runPromise( |
| 867 | harness.engine.dispatch({ | 865 | harness.engine.dispatch({ |
| 868 | type: "thread.turn.diff.complete", | 866 | type: "thread.turn.diff.complete", |
| 869 | commandId: CommandId.makeUnsafe("cmd-diff-1"), | 867 | commandId: CommandId.make("cmd-diff-1"), |
| 870 | threadId: ThreadId.makeUnsafe("thread-1"), | 868 | threadId: ThreadId.make("thread-1"), |
| 871 | turnId: asTurnId("turn-1"), | 869 | turnId: asTurnId("turn-1"), |
| 872 | completedAt: createdAt, | 870 | completedAt: createdAt, |
| 873 | checkpointRef: checkpointRefForThreadTurn(ThreadId.makeUnsafe("thread-1"), 1), | 871 | checkpointRef: checkpointRefForThreadTurn(ThreadId.make("thread-1"), 1), |
| 874 | status: "ready", | 872 | status: "ready", |
| 875 | files: [], | 873 | files: [], |
| 876 | checkpointTurnCount: 1, | 874 | checkpointTurnCount: 1, |
| ... | @@ -880,11 +878,11 @@ describe("CheckpointReactor", () => { | ... | @@ -880,11 +878,11 @@ describe("CheckpointReactor", () => { |
| 880 | await Effect.runPromise( | 878 | await Effect.runPromise( |
| 881 | harness.engine.dispatch({ | 879 | harness.engine.dispatch({ |
| 882 | type: "thread.turn.diff.complete", | 880 | type: "thread.turn.diff.complete", |
| 883 | commandId: CommandId.makeUnsafe("cmd-diff-2"), | 881 | commandId: CommandId.make("cmd-diff-2"), |
| 884 | threadId: ThreadId.makeUnsafe("thread-1"), | 882 | threadId: ThreadId.make("thread-1"), |
| 885 | turnId: asTurnId("turn-2"), | 883 | turnId: asTurnId("turn-2"), |
| 886 | completedAt: createdAt, | 884 | completedAt: createdAt, |
| 887 | checkpointRef: checkpointRefForThreadTurn(ThreadId.makeUnsafe("thread-1"), 2), | 885 | checkpointRef: checkpointRefForThreadTurn(ThreadId.make("thread-1"), 2), |
| 888 | status: "ready", | 886 | status: "ready", |
| 889 | files: [], | 887 | files: [], |
| 890 | checkpointTurnCount: 2, | 888 | checkpointTurnCount: 2, |
| ... | @@ -895,8 +893,8 @@ describe("CheckpointReactor", () => { | ... | @@ -895,8 +893,8 @@ describe("CheckpointReactor", () => { |
| 895 | await Effect.runPromise( | 893 | await Effect.runPromise( |
| 896 | harness.engine.dispatch({ | 894 | harness.engine.dispatch({ |
| 897 | type: "thread.checkpoint.revert", | 895 | type: "thread.checkpoint.revert", |
| 898 | commandId: CommandId.makeUnsafe("cmd-revert-request"), | 896 | commandId: CommandId.make("cmd-revert-request"), |
| 899 | threadId: ThreadId.makeUnsafe("thread-1"), | 897 | threadId: ThreadId.make("thread-1"), |
| 900 | turnCount: 1, | 898 | turnCount: 1, |
| 901 | createdAt, | 899 | createdAt, |
| 902 | }), | 900 | }), |
| ... | @@ -910,12 +908,12 @@ describe("CheckpointReactor", () => { | ... | @@ -910,12 +908,12 @@ describe("CheckpointReactor", () => { |
| 910 | expect(thread.checkpoints[0]?.checkpointTurnCount).toBe(1); | 908 | expect(thread.checkpoints[0]?.checkpointTurnCount).toBe(1); |
| 911 | expect(harness.provider.rollbackConversation).toHaveBeenCalledTimes(1); | 909 | expect(harness.provider.rollbackConversation).toHaveBeenCalledTimes(1); |
| 912 | expect(harness.provider.rollbackConversation).toHaveBeenCalledWith({ | 910 | expect(harness.provider.rollbackConversation).toHaveBeenCalledWith({ |
| 913 | threadId: ThreadId.makeUnsafe("thread-1"), | 911 | threadId: ThreadId.make("thread-1"), |
| 914 | numTurns: 1, | 912 | numTurns: 1, |
| 915 | }); | 913 | }); |
| 916 | expect(fs.readFileSync(path.join(harness.cwd, "README.md"), "utf8")).toBe("v2\n"); | 914 | expect(fs.readFileSync(path.join(harness.cwd, "README.md"), "utf8")).toBe("v2\n"); |
| 917 | expect( | 915 | expect( |
| 918 | gitRefExists(harness.cwd, checkpointRefForThreadTurn(ThreadId.makeUnsafe("thread-1"), 2)), | 916 | gitRefExists(harness.cwd, checkpointRefForThreadTurn(ThreadId.make("thread-1"), 2)), |
| 919 | ).toBe(false); | 917 | ).toBe(false); |
| 920 | }); | 918 | }); |
| 921 | 919 | ||
| ... | @@ -926,10 +924,10 @@ describe("CheckpointReactor", () => { | ... | @@ -926,10 +924,10 @@ describe("CheckpointReactor", () => { |
| 926 | await Effect.runPromise( | 924 | await Effect.runPromise( |
| 927 | harness.engine.dispatch({ | 925 | harness.engine.dispatch({ |
| 928 | type: "thread.session.set", | 926 | type: "thread.session.set", |
| 929 | commandId: CommandId.makeUnsafe("cmd-session-set-claude"), | 927 | commandId: CommandId.make("cmd-session-set-claude"), |
| 930 | threadId: ThreadId.makeUnsafe("thread-1"), | 928 | threadId: ThreadId.make("thread-1"), |
| 931 | session: { | 929 | session: { |
| 932 | threadId: ThreadId.makeUnsafe("thread-1"), | 930 | threadId: ThreadId.make("thread-1"), |
| 933 | status: "ready", | 931 | status: "ready", |
| 934 | providerName: "claudeAgent", | 932 | providerName: "claudeAgent", |
| 935 | runtimeMode: "approval-required", | 933 | runtimeMode: "approval-required", |
| ... | @@ -944,11 +942,11 @@ describe("CheckpointReactor", () => { | ... | @@ -944,11 +942,11 @@ describe("CheckpointReactor", () => { |
| 944 | await Effect.runPromise( | 942 | await Effect.runPromise( |
| 945 | harness.engine.dispatch({ | 943 | harness.engine.dispatch({ |
| 946 | type: "thread.turn.diff.complete", | 944 | type: "thread.turn.diff.complete", |
| 947 | commandId: CommandId.makeUnsafe("cmd-diff-claude-1"), | 945 | commandId: CommandId.make("cmd-diff-claude-1"), |
| 948 | threadId: ThreadId.makeUnsafe("thread-1"), | 946 | threadId: ThreadId.make("thread-1"), |
| 949 | turnId: asTurnId("turn-claude-1"), | 947 | turnId: asTurnId("turn-claude-1"), |
| 950 | completedAt: createdAt, | 948 | completedAt: createdAt, |
| 951 | checkpointRef: checkpointRefForThreadTurn(ThreadId.makeUnsafe("thread-1"), 1), | 949 | checkpointRef: checkpointRefForThreadTurn(ThreadId.make("thread-1"), 1), |
| 952 | status: "ready", | 950 | status: "ready", |
| 953 | files: [], | 951 | files: [], |
| 954 | checkpointTurnCount: 1, | 952 | checkpointTurnCount: 1, |
| ... | @@ -958,11 +956,11 @@ describe("CheckpointReactor", () => { | ... | @@ -958,11 +956,11 @@ describe("CheckpointReactor", () => { |
| 958 | await Effect.runPromise( | 956 | await Effect.runPromise( |
| 959 | harness.engine.dispatch({ | 957 | harness.engine.dispatch({ |
| 960 | type: "thread.turn.diff.complete", | 958 | type: "thread.turn.diff.complete", |
| 961 | commandId: CommandId.makeUnsafe("cmd-diff-claude-2"), | 959 | commandId: CommandId.make("cmd-diff-claude-2"), |
| 962 | threadId: ThreadId.makeUnsafe("thread-1"), | 960 | threadId: ThreadId.make("thread-1"), |
| 963 | turnId: asTurnId("turn-claude-2"), | 961 | turnId: asTurnId("turn-claude-2"), |
| 964 | completedAt: createdAt, | 962 | completedAt: createdAt, |
| 965 | checkpointRef: checkpointRefForThreadTurn(ThreadId.makeUnsafe("thread-1"), 2), | 963 | checkpointRef: checkpointRefForThreadTurn(ThreadId.make("thread-1"), 2), |
| 966 | status: "ready", | 964 | status: "ready", |
| 967 | files: [], | 965 | files: [], |
| 968 | checkpointTurnCount: 2, | 966 | checkpointTurnCount: 2, |
| ... | @@ -973,8 +971,8 @@ describe("CheckpointReactor", () => { | ... | @@ -973,8 +971,8 @@ describe("CheckpointReactor", () => { |
| 973 | await Effect.runPromise( | 971 | await Effect.runPromise( |
| 974 | harness.engine.dispatch({ | 972 | harness.engine.dispatch({ |
| 975 | type: "thread.checkpoint.revert", | 973 | type: "thread.checkpoint.revert", |
| 976 | commandId: CommandId.makeUnsafe("cmd-revert-request-claude"), | 974 | commandId: CommandId.make("cmd-revert-request-claude"), |
| 977 | threadId: ThreadId.makeUnsafe("thread-1"), | 975 | threadId: ThreadId.make("thread-1"), |
| 978 | turnCount: 1, | 976 | turnCount: 1, |
| 979 | createdAt, | 977 | createdAt, |
| 980 | }), | 978 | }), |
| ... | @@ -983,7 +981,7 @@ describe("CheckpointReactor", () => { | ... | @@ -983,7 +981,7 @@ describe("CheckpointReactor", () => { |
| 983 | await waitForEvent(harness.engine, (event) => event.type === "thread.reverted"); | 981 | await waitForEvent(harness.engine, (event) => event.type === "thread.reverted"); |
| 984 | expect(harness.provider.rollbackConversation).toHaveBeenCalledTimes(1); | 982 | expect(harness.provider.rollbackConversation).toHaveBeenCalledTimes(1); |
| 985 | expect(harness.provider.rollbackConversation).toHaveBeenCalledWith({ | 983 | expect(harness.provider.rollbackConversation).toHaveBeenCalledWith({ |
| 986 | threadId: ThreadId.makeUnsafe("thread-1"), | 984 | threadId: ThreadId.make("thread-1"), |
| 987 | numTurns: 1, | 985 | numTurns: 1, |
| 988 | }); | 986 | }); |
| 989 | }); | 987 | }); |
| ... | @@ -995,10 +993,10 @@ describe("CheckpointReactor", () => { | ... | @@ -995,10 +993,10 @@ describe("CheckpointReactor", () => { |
| 995 | await Effect.runPromise( | 993 | await Effect.runPromise( |
| 996 | harness.engine.dispatch({ | 994 | harness.engine.dispatch({ |
| 997 | type: "thread.session.set", | 995 | type: "thread.session.set", |
| 998 | commandId: CommandId.makeUnsafe("cmd-session-set-inline-revert"), | 996 | commandId: CommandId.make("cmd-session-set-inline-revert"), |
| 999 | threadId: ThreadId.makeUnsafe("thread-1"), | 997 | threadId: ThreadId.make("thread-1"), |
| 1000 | session: { | 998 | session: { |
| 1001 | threadId: ThreadId.makeUnsafe("thread-1"), | 999 | threadId: ThreadId.make("thread-1"), |
| 1002 | status: "ready", | 1000 | status: "ready", |
| 1003 | providerName: "codex", | 1001 | providerName: "codex", |
| 1004 | runtimeMode: "approval-required", | 1002 | runtimeMode: "approval-required", |
| ... | @@ -1013,11 +1011,11 @@ describe("CheckpointReactor", () => { | ... | @@ -1013,11 +1011,11 @@ describe("CheckpointReactor", () => { |
| 1013 | await Effect.runPromise( | 1011 | await Effect.runPromise( |
| 1014 | harness.engine.dispatch({ | 1012 | harness.engine.dispatch({ |
| 1015 | type: "thread.turn.diff.complete", | 1013 | type: "thread.turn.diff.complete", |
| 1016 | commandId: CommandId.makeUnsafe("cmd-inline-revert-diff-1"), | 1014 | commandId: CommandId.make("cmd-inline-revert-diff-1"), |
| 1017 | threadId: ThreadId.makeUnsafe("thread-1"), | 1015 | threadId: ThreadId.make("thread-1"), |
| 1018 | turnId: asTurnId("turn-1"), | 1016 | turnId: asTurnId("turn-1"), |
| 1019 | completedAt: createdAt, | 1017 | completedAt: createdAt, |
| 1020 | checkpointRef: checkpointRefForThreadTurn(ThreadId.makeUnsafe("thread-1"), 1), | 1018 | checkpointRef: checkpointRefForThreadTurn(ThreadId.make("thread-1"), 1), |
| 1021 | status: "ready", | 1019 | status: "ready", |
| 1022 | files: [], | 1020 | files: [], |
| 1023 | checkpointTurnCount: 1, | 1021 | checkpointTurnCount: 1, |
| ... | @@ -1027,11 +1025,11 @@ describe("CheckpointReactor", () => { | ... | @@ -1027,11 +1025,11 @@ describe("CheckpointReactor", () => { |
| 1027 | await Effect.runPromise( | 1025 | await Effect.runPromise( |
| 1028 | harness.engine.dispatch({ | 1026 | harness.engine.dispatch({ |
| 1029 | type: "thread.turn.diff.complete", | 1027 | type: "thread.turn.diff.complete", |
| 1030 | commandId: CommandId.makeUnsafe("cmd-inline-revert-diff-2"), | 1028 | commandId: CommandId.make("cmd-inline-revert-diff-2"), |
| 1031 | threadId: ThreadId.makeUnsafe("thread-1"), | 1029 | threadId: ThreadId.make("thread-1"), |
| 1032 | turnId: asTurnId("turn-2"), | 1030 | turnId: asTurnId("turn-2"), |
| 1033 | completedAt: createdAt, | 1031 | completedAt: createdAt, |
| 1034 | checkpointRef: checkpointRefForThreadTurn(ThreadId.makeUnsafe("thread-1"), 2), | 1032 | checkpointRef: checkpointRefForThreadTurn(ThreadId.make("thread-1"), 2), |
| 1035 | status: "ready", | 1033 | status: "ready", |
| 1036 | files: [], | 1034 | files: [], |
| 1037 | checkpointTurnCount: 2, | 1035 | checkpointTurnCount: 2, |
| ... | @@ -1042,8 +1040,8 @@ describe("CheckpointReactor", () => { | ... | @@ -1042,8 +1040,8 @@ describe("CheckpointReactor", () => { |
| 1042 | await Effect.runPromise( | 1040 | await Effect.runPromise( |
| 1043 | harness.engine.dispatch({ | 1041 | harness.engine.dispatch({ |
| 1044 | type: "thread.checkpoint.revert", | 1042 | type: "thread.checkpoint.revert", |
| 1045 | commandId: CommandId.makeUnsafe("cmd-sequenced-revert-request-1"), | 1043 | commandId: CommandId.make("cmd-sequenced-revert-request-1"), |
| 1046 | threadId: ThreadId.makeUnsafe("thread-1"), | 1044 | threadId: ThreadId.make("thread-1"), |
| 1047 | turnCount: 1, | 1045 | turnCount: 1, |
| 1048 | createdAt, | 1046 | createdAt, |
| 1049 | }), | 1047 | }), |
| ... | @@ -1051,8 +1049,8 @@ describe("CheckpointReactor", () => { | ... | @@ -1051,8 +1049,8 @@ describe("CheckpointReactor", () => { |
| 1051 | await Effect.runPromise( | 1049 | await Effect.runPromise( |
| 1052 | harness.engine.dispatch({ | 1050 | harness.engine.dispatch({ |
| 1053 | type: "thread.checkpoint.revert", | 1051 | type: "thread.checkpoint.revert", |
| 1054 | commandId: CommandId.makeUnsafe("cmd-sequenced-revert-request-0"), | 1052 | commandId: CommandId.make("cmd-sequenced-revert-request-0"), |
| 1055 | threadId: ThreadId.makeUnsafe("thread-1"), | 1053 | threadId: ThreadId.make("thread-1"), |
| 1056 | turnCount: 0, | 1054 | turnCount: 0, |
| 1057 | createdAt, | 1055 | createdAt, |
| 1058 | }), | 1056 | }), |
| ... | @@ -1062,11 +1060,11 @@ describe("CheckpointReactor", () => { | ... | @@ -1062,11 +1060,11 @@ describe("CheckpointReactor", () => { |
| 1062 | 1060 | ||
| 1063 | expect(harness.provider.rollbackConversation).toHaveBeenCalledTimes(2); | 1061 | expect(harness.provider.rollbackConversation).toHaveBeenCalledTimes(2); |
| 1064 | expect(harness.provider.rollbackConversation.mock.calls[0]?.[0]).toEqual({ | 1062 | expect(harness.provider.rollbackConversation.mock.calls[0]?.[0]).toEqual({ |
| 1065 | threadId: ThreadId.makeUnsafe("thread-1"), | 1063 | threadId: ThreadId.make("thread-1"), |
| 1066 | numTurns: 1, | 1064 | numTurns: 1, |
| 1067 | }); | 1065 | }); |
| 1068 | expect(harness.provider.rollbackConversation.mock.calls[1]?.[0]).toEqual({ | 1066 | expect(harness.provider.rollbackConversation.mock.calls[1]?.[0]).toEqual({ |
| 1069 | threadId: ThreadId.makeUnsafe("thread-1"), | 1067 | threadId: ThreadId.make("thread-1"), |
| 1070 | numTurns: 1, | 1068 | numTurns: 1, |
| 1071 | }); | 1069 | }); |
| 1072 | }); | 1070 | }); |
| ... | @@ -1078,8 +1076,8 @@ describe("CheckpointReactor", () => { | ... | @@ -1078,8 +1076,8 @@ describe("CheckpointReactor", () => { |
| 1078 | await Effect.runPromise( | 1076 | await Effect.runPromise( |
| 1079 | harness.engine.dispatch({ | 1077 | harness.engine.dispatch({ |
| 1080 | type: "thread.checkpoint.revert", | 1078 | type: "thread.checkpoint.revert", |
| 1081 | commandId: CommandId.makeUnsafe("cmd-revert-no-session"), | 1079 | commandId: CommandId.make("cmd-revert-no-session"), |
| 1082 | threadId: ThreadId.makeUnsafe("thread-1"), | 1080 | threadId: ThreadId.make("thread-1"), |
| 1083 | turnCount: 1, | 1081 | turnCount: 1, |
| 1084 | createdAt, | 1082 | createdAt, |
| 1085 | }), | 1083 | }), |
apps/server/src/orchestration/Layers/CheckpointReactor.ts+6-6| ... | @@ -38,7 +38,7 @@ type ReactorInput = | ... | @@ -38,7 +38,7 @@ type ReactorInput = |
| 38 | }; | 38 | }; |
| 39 | 39 | ||
| 40 | function toTurnId(value: string | undefined): TurnId | null { | 40 | function toTurnId(value: string | undefined): TurnId | null { |
| 41 | return value === undefined ? null : TurnId.makeUnsafe(String(value)); | 41 | return value === undefined ? null : TurnId.make(String(value)); |
| 42 | } | 42 | } |
| 43 | 43 | ||
| 44 | function sameId(left: string | null | undefined, right: string | null | undefined): boolean { | 44 | function sameId(left: string | null | undefined, right: string | null | undefined): boolean { |
| ... | @@ -62,7 +62,7 @@ function checkpointStatusFromRuntime(status: string | undefined): "ready" | "mis | ... | @@ -62,7 +62,7 @@ function checkpointStatusFromRuntime(status: string | undefined): "ready" | "mis |
| 62 | } | 62 | } |
| 63 | 63 | ||
| 64 | const serverCommandId = (tag: string): CommandId => | 64 | const serverCommandId = (tag: string): CommandId => |
| 65 | CommandId.makeUnsafe(`server:${tag}:${crypto.randomUUID()}`); | 65 | CommandId.make(`server:${tag}:${crypto.randomUUID()}`); |
| 66 | 66 | ||
| 67 | const make = Effect.gen(function* () { | 67 | const make = Effect.gen(function* () { |
| 68 | const orchestrationEngine = yield* OrchestrationEngineService; | 68 | const orchestrationEngine = yield* OrchestrationEngineService; |
| ... | @@ -83,7 +83,7 @@ const make = Effect.gen(function* () { | ... | @@ -83,7 +83,7 @@ const make = Effect.gen(function* () { |
| 83 | commandId: serverCommandId("checkpoint-revert-failure"), | 83 | commandId: serverCommandId("checkpoint-revert-failure"), |
| 84 | threadId: input.threadId, | 84 | threadId: input.threadId, |
| 85 | activity: { | 85 | activity: { |
| 86 | id: EventId.makeUnsafe(crypto.randomUUID()), | 86 | id: EventId.make(crypto.randomUUID()), |
| 87 | tone: "error", | 87 | tone: "error", |
| 88 | kind: "checkpoint.revert.failed", | 88 | kind: "checkpoint.revert.failed", |
| 89 | summary: "Checkpoint revert failed", | 89 | summary: "Checkpoint revert failed", |
| ... | @@ -108,7 +108,7 @@ const make = Effect.gen(function* () { | ... | @@ -108,7 +108,7 @@ const make = Effect.gen(function* () { |
| 108 | commandId: serverCommandId("checkpoint-capture-failure"), | 108 | commandId: serverCommandId("checkpoint-capture-failure"), |
| 109 | threadId: input.threadId, | 109 | threadId: input.threadId, |
| 110 | activity: { | 110 | activity: { |
| 111 | id: EventId.makeUnsafe(crypto.randomUUID()), | 111 | id: EventId.make(crypto.randomUUID()), |
| 112 | tone: "error", | 112 | tone: "error", |
| 113 | kind: "checkpoint.capture.failed", | 113 | kind: "checkpoint.capture.failed", |
| 114 | summary: "Checkpoint capture failed", | 114 | summary: "Checkpoint capture failed", |
| ... | @@ -270,7 +270,7 @@ const make = Effect.gen(function* () { | ... | @@ -270,7 +270,7 @@ const make = Effect.gen(function* () { |
| 270 | input.thread.messages | 270 | input.thread.messages |
| 271 | .toReversed() | 271 | .toReversed() |
| 272 | .find((entry) => entry.role === "assistant" && entry.turnId === input.turnId)?.id ?? | 272 | .find((entry) => entry.role === "assistant" && entry.turnId === input.turnId)?.id ?? |
| 273 | MessageId.makeUnsafe(`assistant:${input.turnId}`); | 273 | MessageId.make(`assistant:${input.turnId}`); |
| 274 | 274 | ||
| 275 | yield* orchestrationEngine.dispatch({ | 275 | yield* orchestrationEngine.dispatch({ |
| 276 | type: "thread.turn.diff.complete", | 276 | type: "thread.turn.diff.complete", |
| ... | @@ -307,7 +307,7 @@ const make = Effect.gen(function* () { | ... | @@ -307,7 +307,7 @@ const make = Effect.gen(function* () { |
| 307 | commandId: serverCommandId("checkpoint-captured-activity"), | 307 | commandId: serverCommandId("checkpoint-captured-activity"), |
| 308 | threadId: input.threadId, | 308 | threadId: input.threadId, |
| 309 | activity: { | 309 | activity: { |
| 310 | id: EventId.makeUnsafe(crypto.randomUUID()), | 310 | id: EventId.make(crypto.randomUUID()), |
| 311 | tone: "info", | 311 | tone: "info", |
| 312 | kind: "checkpoint.captured", | 312 | kind: "checkpoint.captured", |
| 313 | summary: "Checkpoint captured", | 313 | summary: "Checkpoint captured", |
apps/server/src/orchestration/Layers/OrchestrationEngine.test.ts+62-62| ... | @@ -32,10 +32,10 @@ import { ProjectionSnapshotQuery } from "../Services/ProjectionSnapshotQuery.ts" | ... | @@ -32,10 +32,10 @@ import { ProjectionSnapshotQuery } from "../Services/ProjectionSnapshotQuery.ts" |
| 32 | import { ServerConfig } from "../../config.ts"; | 32 | import { ServerConfig } from "../../config.ts"; |
| 33 | import * as NodeServices from "@effect/platform-node/NodeServices"; | 33 | import * as NodeServices from "@effect/platform-node/NodeServices"; |
| 34 | 34 | ||
| 35 | const asProjectId = (value: string): ProjectId => ProjectId.makeUnsafe(value); | 35 | const asProjectId = (value: string): ProjectId => ProjectId.make(value); |
| 36 | const asMessageId = (value: string): MessageId => MessageId.makeUnsafe(value); | 36 | const asMessageId = (value: string): MessageId => MessageId.make(value); |
| 37 | const asTurnId = (value: string): TurnId => TurnId.makeUnsafe(value); | 37 | const asTurnId = (value: string): TurnId => TurnId.make(value); |
| 38 | const asCheckpointRef = (value: string): CheckpointRef => CheckpointRef.makeUnsafe(value); | 38 | const asCheckpointRef = (value: string): CheckpointRef => CheckpointRef.make(value); |
| 39 | 39 | ||
| 40 | async function createOrchestrationSystem() { | 40 | async function createOrchestrationSystem() { |
| 41 | const ServerConfigLayer = ServerConfig.layerTest(process.cwd(), { | 41 | const ServerConfigLayer = ServerConfig.layerTest(process.cwd(), { |
| ... | @@ -115,7 +115,7 @@ describe("OrchestrationEngine", () => { | ... | @@ -115,7 +115,7 @@ describe("OrchestrationEngine", () => { |
| 115 | ], | 115 | ], |
| 116 | threads: [ | 116 | threads: [ |
| 117 | { | 117 | { |
| 118 | id: ThreadId.makeUnsafe("thread-bootstrap"), | 118 | id: ThreadId.make("thread-bootstrap"), |
| 119 | projectId: asProjectId("project-bootstrap"), | 119 | projectId: asProjectId("project-bootstrap"), |
| 120 | title: "Bootstrap Thread", | 120 | title: "Bootstrap Thread", |
| 121 | modelSelection: { | 121 | modelSelection: { |
| ... | @@ -183,7 +183,7 @@ describe("OrchestrationEngine", () => { | ... | @@ -183,7 +183,7 @@ describe("OrchestrationEngine", () => { |
| 183 | await system.run( | 183 | await system.run( |
| 184 | engine.dispatch({ | 184 | engine.dispatch({ |
| 185 | type: "project.create", | 185 | type: "project.create", |
| 186 | commandId: CommandId.makeUnsafe("cmd-project-1-create"), | 186 | commandId: CommandId.make("cmd-project-1-create"), |
| 187 | projectId: asProjectId("project-1"), | 187 | projectId: asProjectId("project-1"), |
| 188 | title: "Project 1", | 188 | title: "Project 1", |
| 189 | workspaceRoot: "/tmp/project-1", | 189 | workspaceRoot: "/tmp/project-1", |
| ... | @@ -197,8 +197,8 @@ describe("OrchestrationEngine", () => { | ... | @@ -197,8 +197,8 @@ describe("OrchestrationEngine", () => { |
| 197 | await system.run( | 197 | await system.run( |
| 198 | engine.dispatch({ | 198 | engine.dispatch({ |
| 199 | type: "thread.create", | 199 | type: "thread.create", |
| 200 | commandId: CommandId.makeUnsafe("cmd-thread-1-create"), | 200 | commandId: CommandId.make("cmd-thread-1-create"), |
| 201 | threadId: ThreadId.makeUnsafe("thread-1"), | 201 | threadId: ThreadId.make("thread-1"), |
| 202 | projectId: asProjectId("project-1"), | 202 | projectId: asProjectId("project-1"), |
| 203 | title: "Thread", | 203 | title: "Thread", |
| 204 | modelSelection: { | 204 | modelSelection: { |
| ... | @@ -215,8 +215,8 @@ describe("OrchestrationEngine", () => { | ... | @@ -215,8 +215,8 @@ describe("OrchestrationEngine", () => { |
| 215 | await system.run( | 215 | await system.run( |
| 216 | engine.dispatch({ | 216 | engine.dispatch({ |
| 217 | type: "thread.turn.start", | 217 | type: "thread.turn.start", |
| 218 | commandId: CommandId.makeUnsafe("cmd-turn-start-1"), | 218 | commandId: CommandId.make("cmd-turn-start-1"), |
| 219 | threadId: ThreadId.makeUnsafe("thread-1"), | 219 | threadId: ThreadId.make("thread-1"), |
| 220 | message: { | 220 | message: { |
| 221 | messageId: asMessageId("msg-1"), | 221 | messageId: asMessageId("msg-1"), |
| 222 | role: "user", | 222 | role: "user", |
| ... | @@ -243,7 +243,7 @@ describe("OrchestrationEngine", () => { | ... | @@ -243,7 +243,7 @@ describe("OrchestrationEngine", () => { |
| 243 | await system.run( | 243 | await system.run( |
| 244 | engine.dispatch({ | 244 | engine.dispatch({ |
| 245 | type: "project.create", | 245 | type: "project.create", |
| 246 | commandId: CommandId.makeUnsafe("cmd-project-archive-create"), | 246 | commandId: CommandId.make("cmd-project-archive-create"), |
| 247 | projectId: asProjectId("project-archive"), | 247 | projectId: asProjectId("project-archive"), |
| 248 | title: "Project Archive", | 248 | title: "Project Archive", |
| 249 | workspaceRoot: "/tmp/project-archive", | 249 | workspaceRoot: "/tmp/project-archive", |
| ... | @@ -257,8 +257,8 @@ describe("OrchestrationEngine", () => { | ... | @@ -257,8 +257,8 @@ describe("OrchestrationEngine", () => { |
| 257 | await system.run( | 257 | await system.run( |
| 258 | engine.dispatch({ | 258 | engine.dispatch({ |
| 259 | type: "thread.create", | 259 | type: "thread.create", |
| 260 | commandId: CommandId.makeUnsafe("cmd-thread-archive-create"), | 260 | commandId: CommandId.make("cmd-thread-archive-create"), |
| 261 | threadId: ThreadId.makeUnsafe("thread-archive"), | 261 | threadId: ThreadId.make("thread-archive"), |
| 262 | projectId: asProjectId("project-archive"), | 262 | projectId: asProjectId("project-archive"), |
| 263 | title: "Archive me", | 263 | title: "Archive me", |
| 264 | modelSelection: { | 264 | modelSelection: { |
| ... | @@ -276,8 +276,8 @@ describe("OrchestrationEngine", () => { | ... | @@ -276,8 +276,8 @@ describe("OrchestrationEngine", () => { |
| 276 | await system.run( | 276 | await system.run( |
| 277 | engine.dispatch({ | 277 | engine.dispatch({ |
| 278 | type: "thread.archive", | 278 | type: "thread.archive", |
| 279 | commandId: CommandId.makeUnsafe("cmd-thread-archive"), | 279 | commandId: CommandId.make("cmd-thread-archive"), |
| 280 | threadId: ThreadId.makeUnsafe("thread-archive"), | 280 | threadId: ThreadId.make("thread-archive"), |
| 281 | }), | 281 | }), |
| 282 | ); | 282 | ); |
| 283 | expect( | 283 | expect( |
| ... | @@ -289,8 +289,8 @@ describe("OrchestrationEngine", () => { | ... | @@ -289,8 +289,8 @@ describe("OrchestrationEngine", () => { |
| 289 | await system.run( | 289 | await system.run( |
| 290 | engine.dispatch({ | 290 | engine.dispatch({ |
| 291 | type: "thread.unarchive", | 291 | type: "thread.unarchive", |
| 292 | commandId: CommandId.makeUnsafe("cmd-thread-unarchive"), | 292 | commandId: CommandId.make("cmd-thread-unarchive"), |
| 293 | threadId: ThreadId.makeUnsafe("thread-archive"), | 293 | threadId: ThreadId.make("thread-archive"), |
| 294 | }), | 294 | }), |
| 295 | ); | 295 | ); |
| 296 | expect( | 296 | expect( |
| ... | @@ -310,7 +310,7 @@ describe("OrchestrationEngine", () => { | ... | @@ -310,7 +310,7 @@ describe("OrchestrationEngine", () => { |
| 310 | await system.run( | 310 | await system.run( |
| 311 | engine.dispatch({ | 311 | engine.dispatch({ |
| 312 | type: "project.create", | 312 | type: "project.create", |
| 313 | commandId: CommandId.makeUnsafe("cmd-project-replay-create"), | 313 | commandId: CommandId.make("cmd-project-replay-create"), |
| 314 | projectId: asProjectId("project-replay"), | 314 | projectId: asProjectId("project-replay"), |
| 315 | title: "Replay Project", | 315 | title: "Replay Project", |
| 316 | workspaceRoot: "/tmp/project-replay", | 316 | workspaceRoot: "/tmp/project-replay", |
| ... | @@ -324,8 +324,8 @@ describe("OrchestrationEngine", () => { | ... | @@ -324,8 +324,8 @@ describe("OrchestrationEngine", () => { |
| 324 | await system.run( | 324 | await system.run( |
| 325 | engine.dispatch({ | 325 | engine.dispatch({ |
| 326 | type: "thread.create", | 326 | type: "thread.create", |
| 327 | commandId: CommandId.makeUnsafe("cmd-thread-replay-create"), | 327 | commandId: CommandId.make("cmd-thread-replay-create"), |
| 328 | threadId: ThreadId.makeUnsafe("thread-replay"), | 328 | threadId: ThreadId.make("thread-replay"), |
| 329 | projectId: asProjectId("project-replay"), | 329 | projectId: asProjectId("project-replay"), |
| 330 | title: "replay", | 330 | title: "replay", |
| 331 | modelSelection: { | 331 | modelSelection: { |
| ... | @@ -342,8 +342,8 @@ describe("OrchestrationEngine", () => { | ... | @@ -342,8 +342,8 @@ describe("OrchestrationEngine", () => { |
| 342 | await system.run( | 342 | await system.run( |
| 343 | engine.dispatch({ | 343 | engine.dispatch({ |
| 344 | type: "thread.delete", | 344 | type: "thread.delete", |
| 345 | commandId: CommandId.makeUnsafe("cmd-thread-replay-delete"), | 345 | commandId: CommandId.make("cmd-thread-replay-delete"), |
| 346 | threadId: ThreadId.makeUnsafe("thread-replay"), | 346 | threadId: ThreadId.make("thread-replay"), |
| 347 | }), | 347 | }), |
| 348 | ); | 348 | ); |
| 349 | 349 | ||
| ... | @@ -368,7 +368,7 @@ describe("OrchestrationEngine", () => { | ... | @@ -368,7 +368,7 @@ describe("OrchestrationEngine", () => { |
| 368 | await system.run( | 368 | await system.run( |
| 369 | engine.dispatch({ | 369 | engine.dispatch({ |
| 370 | type: "project.create", | 370 | type: "project.create", |
| 371 | commandId: CommandId.makeUnsafe("cmd-project-stream-create"), | 371 | commandId: CommandId.make("cmd-project-stream-create"), |
| 372 | projectId: asProjectId("project-stream"), | 372 | projectId: asProjectId("project-stream"), |
| 373 | title: "Stream Project", | 373 | title: "Stream Project", |
| 374 | workspaceRoot: "/tmp/project-stream", | 374 | workspaceRoot: "/tmp/project-stream", |
| ... | @@ -392,8 +392,8 @@ describe("OrchestrationEngine", () => { | ... | @@ -392,8 +392,8 @@ describe("OrchestrationEngine", () => { |
| 392 | yield* Effect.sleep("10 millis"); | 392 | yield* Effect.sleep("10 millis"); |
| 393 | yield* engine.dispatch({ | 393 | yield* engine.dispatch({ |
| 394 | type: "thread.create", | 394 | type: "thread.create", |
| 395 | commandId: CommandId.makeUnsafe("cmd-stream-thread-create"), | 395 | commandId: CommandId.make("cmd-stream-thread-create"), |
| 396 | threadId: ThreadId.makeUnsafe("thread-stream"), | 396 | threadId: ThreadId.make("thread-stream"), |
| 397 | projectId: asProjectId("project-stream"), | 397 | projectId: asProjectId("project-stream"), |
| 398 | title: "domain-stream", | 398 | title: "domain-stream", |
| 399 | modelSelection: { | 399 | modelSelection: { |
| ... | @@ -408,8 +408,8 @@ describe("OrchestrationEngine", () => { | ... | @@ -408,8 +408,8 @@ describe("OrchestrationEngine", () => { |
| 408 | }); | 408 | }); |
| 409 | yield* engine.dispatch({ | 409 | yield* engine.dispatch({ |
| 410 | type: "thread.meta.update", | 410 | type: "thread.meta.update", |
| 411 | commandId: CommandId.makeUnsafe("cmd-stream-thread-update"), | 411 | commandId: CommandId.make("cmd-stream-thread-update"), |
| 412 | threadId: ThreadId.makeUnsafe("thread-stream"), | 412 | threadId: ThreadId.make("thread-stream"), |
| 413 | title: "domain-stream-updated", | 413 | title: "domain-stream-updated", |
| 414 | }); | 414 | }); |
| 415 | eventTypes.push((yield* Queue.take(eventQueue)).type); | 415 | eventTypes.push((yield* Queue.take(eventQueue)).type); |
| ... | @@ -429,7 +429,7 @@ describe("OrchestrationEngine", () => { | ... | @@ -429,7 +429,7 @@ describe("OrchestrationEngine", () => { |
| 429 | await system.run( | 429 | await system.run( |
| 430 | engine.dispatch({ | 430 | engine.dispatch({ |
| 431 | type: "project.create", | 431 | type: "project.create", |
| 432 | commandId: CommandId.makeUnsafe("cmd-project-ack-create"), | 432 | commandId: CommandId.make("cmd-project-ack-create"), |
| 433 | projectId: asProjectId("project-ack"), | 433 | projectId: asProjectId("project-ack"), |
| 434 | title: "Ack Project", | 434 | title: "Ack Project", |
| 435 | workspaceRoot: "/tmp/project-ack", | 435 | workspaceRoot: "/tmp/project-ack", |
| ... | @@ -444,8 +444,8 @@ describe("OrchestrationEngine", () => { | ... | @@ -444,8 +444,8 @@ describe("OrchestrationEngine", () => { |
| 444 | await system.run( | 444 | await system.run( |
| 445 | engine.dispatch({ | 445 | engine.dispatch({ |
| 446 | type: "thread.create", | 446 | type: "thread.create", |
| 447 | commandId: CommandId.makeUnsafe("cmd-thread-ack-create"), | 447 | commandId: CommandId.make("cmd-thread-ack-create"), |
| 448 | threadId: ThreadId.makeUnsafe("thread-ack"), | 448 | threadId: ThreadId.make("thread-ack"), |
| 449 | projectId: asProjectId("project-ack"), | 449 | projectId: asProjectId("project-ack"), |
| 450 | title: "Ack Thread", | 450 | title: "Ack Thread", |
| 451 | modelSelection: { | 451 | modelSelection: { |
| ... | @@ -481,8 +481,8 @@ describe("OrchestrationEngine", () => { | ... | @@ -481,8 +481,8 @@ describe("OrchestrationEngine", () => { |
| 481 | system.run( | 481 | system.run( |
| 482 | engine.dispatch({ | 482 | engine.dispatch({ |
| 483 | type: "thread.create", | 483 | type: "thread.create", |
| 484 | commandId: CommandId.makeUnsafe("cmd-thread-missing-project"), | 484 | commandId: CommandId.make("cmd-thread-missing-project"), |
| 485 | threadId: ThreadId.makeUnsafe("thread-missing-project"), | 485 | threadId: ThreadId.make("thread-missing-project"), |
| 486 | projectId: asProjectId("project-missing"), | 486 | projectId: asProjectId("project-missing"), |
| 487 | title: "Missing Project Thread", | 487 | title: "Missing Project Thread", |
| 488 | modelSelection: { | 488 | modelSelection: { |
| ... | @@ -518,7 +518,7 @@ describe("OrchestrationEngine", () => { | ... | @@ -518,7 +518,7 @@ describe("OrchestrationEngine", () => { |
| 518 | await system.run( | 518 | await system.run( |
| 519 | engine.dispatch({ | 519 | engine.dispatch({ |
| 520 | type: "project.create", | 520 | type: "project.create", |
| 521 | commandId: CommandId.makeUnsafe("cmd-project-turn-diff-create"), | 521 | commandId: CommandId.make("cmd-project-turn-diff-create"), |
| 522 | projectId: asProjectId("project-turn-diff"), | 522 | projectId: asProjectId("project-turn-diff"), |
| 523 | title: "Turn Diff Project", | 523 | title: "Turn Diff Project", |
| 524 | workspaceRoot: "/tmp/project-turn-diff", | 524 | workspaceRoot: "/tmp/project-turn-diff", |
| ... | @@ -532,8 +532,8 @@ describe("OrchestrationEngine", () => { | ... | @@ -532,8 +532,8 @@ describe("OrchestrationEngine", () => { |
| 532 | await system.run( | 532 | await system.run( |
| 533 | engine.dispatch({ | 533 | engine.dispatch({ |
| 534 | type: "thread.create", | 534 | type: "thread.create", |
| 535 | commandId: CommandId.makeUnsafe("cmd-thread-turn-diff-create"), | 535 | commandId: CommandId.make("cmd-thread-turn-diff-create"), |
| 536 | threadId: ThreadId.makeUnsafe("thread-turn-diff"), | 536 | threadId: ThreadId.make("thread-turn-diff"), |
| 537 | projectId: asProjectId("project-turn-diff"), | 537 | projectId: asProjectId("project-turn-diff"), |
| 538 | title: "Turn diff thread", | 538 | title: "Turn diff thread", |
| 539 | modelSelection: { | 539 | modelSelection: { |
| ... | @@ -550,8 +550,8 @@ describe("OrchestrationEngine", () => { | ... | @@ -550,8 +550,8 @@ describe("OrchestrationEngine", () => { |
| 550 | await system.run( | 550 | await system.run( |
| 551 | engine.dispatch({ | 551 | engine.dispatch({ |
| 552 | type: "thread.turn.diff.complete", | 552 | type: "thread.turn.diff.complete", |
| 553 | commandId: CommandId.makeUnsafe("cmd-turn-diff-complete"), | 553 | commandId: CommandId.make("cmd-turn-diff-complete"), |
| 554 | threadId: ThreadId.makeUnsafe("thread-turn-diff"), | 554 | threadId: ThreadId.make("thread-turn-diff"), |
| 555 | turnId: asTurnId("turn-1"), | 555 | turnId: asTurnId("turn-1"), |
| 556 | completedAt: createdAt, | 556 | completedAt: createdAt, |
| 557 | checkpointRef: asCheckpointRef("refs/t3/checkpoints/thread-turn-diff/turn/1"), | 557 | checkpointRef: asCheckpointRef("refs/t3/checkpoints/thread-turn-diff/turn/1"), |
| ... | @@ -590,7 +590,7 @@ describe("OrchestrationEngine", () => { | ... | @@ -590,7 +590,7 @@ describe("OrchestrationEngine", () => { |
| 590 | 590 | ||
| 591 | const flakyStore: OrchestrationEventStoreShape = { | 591 | const flakyStore: OrchestrationEventStoreShape = { |
| 592 | append(event) { | 592 | append(event) { |
| 593 | if (shouldFailFirstAppend && event.commandId === CommandId.makeUnsafe("cmd-flaky-1")) { | 593 | if (shouldFailFirstAppend && event.commandId === CommandId.make("cmd-flaky-1")) { |
| 594 | shouldFailFirstAppend = false; | 594 | shouldFailFirstAppend = false; |
| 595 | return Effect.fail( | 595 | return Effect.fail( |
| 596 | new PersistenceSqlError({ | 596 | new PersistenceSqlError({ |
| ... | @@ -637,7 +637,7 @@ describe("OrchestrationEngine", () => { | ... | @@ -637,7 +637,7 @@ describe("OrchestrationEngine", () => { |
| 637 | await runtime.runPromise( | 637 | await runtime.runPromise( |
| 638 | engine.dispatch({ | 638 | engine.dispatch({ |
| 639 | type: "project.create", | 639 | type: "project.create", |
| 640 | commandId: CommandId.makeUnsafe("cmd-project-flaky-create"), | 640 | commandId: CommandId.make("cmd-project-flaky-create"), |
| 641 | projectId: asProjectId("project-flaky"), | 641 | projectId: asProjectId("project-flaky"), |
| 642 | title: "Flaky Project", | 642 | title: "Flaky Project", |
| 643 | workspaceRoot: "/tmp/project-flaky", | 643 | workspaceRoot: "/tmp/project-flaky", |
| ... | @@ -653,8 +653,8 @@ describe("OrchestrationEngine", () => { | ... | @@ -653,8 +653,8 @@ describe("OrchestrationEngine", () => { |
| 653 | runtime.runPromise( | 653 | runtime.runPromise( |
| 654 | engine.dispatch({ | 654 | engine.dispatch({ |
| 655 | type: "thread.create", | 655 | type: "thread.create", |
| 656 | commandId: CommandId.makeUnsafe("cmd-flaky-1"), | 656 | commandId: CommandId.make("cmd-flaky-1"), |
| 657 | threadId: ThreadId.makeUnsafe("thread-flaky-fail"), | 657 | threadId: ThreadId.make("thread-flaky-fail"), |
| 658 | projectId: asProjectId("project-flaky"), | 658 | projectId: asProjectId("project-flaky"), |
| 659 | title: "flaky-fail", | 659 | title: "flaky-fail", |
| 660 | modelSelection: { | 660 | modelSelection: { |
| ... | @@ -673,8 +673,8 @@ describe("OrchestrationEngine", () => { | ... | @@ -673,8 +673,8 @@ describe("OrchestrationEngine", () => { |
| 673 | const result = await runtime.runPromise( | 673 | const result = await runtime.runPromise( |
| 674 | engine.dispatch({ | 674 | engine.dispatch({ |
| 675 | type: "thread.create", | 675 | type: "thread.create", |
| 676 | commandId: CommandId.makeUnsafe("cmd-flaky-2"), | 676 | commandId: CommandId.make("cmd-flaky-2"), |
| 677 | threadId: ThreadId.makeUnsafe("thread-flaky-ok"), | 677 | threadId: ThreadId.make("thread-flaky-ok"), |
| 678 | projectId: asProjectId("project-flaky"), | 678 | projectId: asProjectId("project-flaky"), |
| 679 | title: "flaky-ok", | 679 | title: "flaky-ok", |
| 680 | modelSelection: { | 680 | modelSelection: { |
| ... | @@ -701,7 +701,7 @@ describe("OrchestrationEngine", () => { | ... | @@ -701,7 +701,7 @@ describe("OrchestrationEngine", () => { |
| 701 | projectEvent: (event) => { | 701 | projectEvent: (event) => { |
| 702 | if ( | 702 | if ( |
| 703 | shouldFailRequestedProjection && | 703 | shouldFailRequestedProjection && |
| 704 | event.commandId === CommandId.makeUnsafe("cmd-turn-start-atomic") && | 704 | event.commandId === CommandId.make("cmd-turn-start-atomic") && |
| 705 | event.type === "thread.turn-start-requested" | 705 | event.type === "thread.turn-start-requested" |
| 706 | ) { | 706 | ) { |
| 707 | shouldFailRequestedProjection = false; | 707 | shouldFailRequestedProjection = false; |
| ... | @@ -732,7 +732,7 @@ describe("OrchestrationEngine", () => { | ... | @@ -732,7 +732,7 @@ describe("OrchestrationEngine", () => { |
| 732 | await runtime.runPromise( | 732 | await runtime.runPromise( |
| 733 | engine.dispatch({ | 733 | engine.dispatch({ |
| 734 | type: "project.create", | 734 | type: "project.create", |
| 735 | commandId: CommandId.makeUnsafe("cmd-project-atomic-create"), | 735 | commandId: CommandId.make("cmd-project-atomic-create"), |
| 736 | projectId: asProjectId("project-atomic"), | 736 | projectId: asProjectId("project-atomic"), |
| 737 | title: "Atomic Project", | 737 | title: "Atomic Project", |
| 738 | workspaceRoot: "/tmp/project-atomic", | 738 | workspaceRoot: "/tmp/project-atomic", |
| ... | @@ -746,8 +746,8 @@ describe("OrchestrationEngine", () => { | ... | @@ -746,8 +746,8 @@ describe("OrchestrationEngine", () => { |
| 746 | await runtime.runPromise( | 746 | await runtime.runPromise( |
| 747 | engine.dispatch({ | 747 | engine.dispatch({ |
| 748 | type: "thread.create", | 748 | type: "thread.create", |
| 749 | commandId: CommandId.makeUnsafe("cmd-thread-atomic-create"), | 749 | commandId: CommandId.make("cmd-thread-atomic-create"), |
| 750 | threadId: ThreadId.makeUnsafe("thread-atomic"), | 750 | threadId: ThreadId.make("thread-atomic"), |
| 751 | projectId: asProjectId("project-atomic"), | 751 | projectId: asProjectId("project-atomic"), |
| 752 | title: "atomic", | 752 | title: "atomic", |
| 753 | modelSelection: { | 753 | modelSelection: { |
| ... | @@ -764,8 +764,8 @@ describe("OrchestrationEngine", () => { | ... | @@ -764,8 +764,8 @@ describe("OrchestrationEngine", () => { |
| 764 | 764 | ||
| 765 | const turnStartCommand = { | 765 | const turnStartCommand = { |
| 766 | type: "thread.turn.start" as const, | 766 | type: "thread.turn.start" as const, |
| 767 | commandId: CommandId.makeUnsafe("cmd-turn-start-atomic"), | 767 | commandId: CommandId.make("cmd-turn-start-atomic"), |
| 768 | threadId: ThreadId.makeUnsafe("thread-atomic"), | 768 | threadId: ThreadId.make("thread-atomic"), |
| 769 | message: { | 769 | message: { |
| 770 | messageId: asMessageId("msg-atomic-1"), | 770 | messageId: asMessageId("msg-atomic-1"), |
| 771 | role: "user" as const, | 771 | role: "user" as const, |
| ... | @@ -845,7 +845,7 @@ describe("OrchestrationEngine", () => { | ... | @@ -845,7 +845,7 @@ describe("OrchestrationEngine", () => { |
| 845 | projectEvent: (event) => { | 845 | projectEvent: (event) => { |
| 846 | if ( | 846 | if ( |
| 847 | shouldFailProjection && | 847 | shouldFailProjection && |
| 848 | event.commandId === CommandId.makeUnsafe("cmd-thread-meta-sync-fail") | 848 | event.commandId === CommandId.make("cmd-thread-meta-sync-fail") |
| 849 | ) { | 849 | ) { |
| 850 | shouldFailProjection = false; | 850 | shouldFailProjection = false; |
| 851 | return Effect.fail( | 851 | return Effect.fail( |
| ... | @@ -875,7 +875,7 @@ describe("OrchestrationEngine", () => { | ... | @@ -875,7 +875,7 @@ describe("OrchestrationEngine", () => { |
| 875 | await runtime.runPromise( | 875 | await runtime.runPromise( |
| 876 | engine.dispatch({ | 876 | engine.dispatch({ |
| 877 | type: "project.create", | 877 | type: "project.create", |
| 878 | commandId: CommandId.makeUnsafe("cmd-project-sync-create"), | 878 | commandId: CommandId.make("cmd-project-sync-create"), |
| 879 | projectId: asProjectId("project-sync"), | 879 | projectId: asProjectId("project-sync"), |
| 880 | title: "Sync Project", | 880 | title: "Sync Project", |
| 881 | workspaceRoot: "/tmp/project-sync", | 881 | workspaceRoot: "/tmp/project-sync", |
| ... | @@ -889,8 +889,8 @@ describe("OrchestrationEngine", () => { | ... | @@ -889,8 +889,8 @@ describe("OrchestrationEngine", () => { |
| 889 | await runtime.runPromise( | 889 | await runtime.runPromise( |
| 890 | engine.dispatch({ | 890 | engine.dispatch({ |
| 891 | type: "thread.create", | 891 | type: "thread.create", |
| 892 | commandId: CommandId.makeUnsafe("cmd-thread-sync-create"), | 892 | commandId: CommandId.make("cmd-thread-sync-create"), |
| 893 | threadId: ThreadId.makeUnsafe("thread-sync"), | 893 | threadId: ThreadId.make("thread-sync"), |
| 894 | projectId: asProjectId("project-sync"), | 894 | projectId: asProjectId("project-sync"), |
| 895 | title: "sync-before", | 895 | title: "sync-before", |
| 896 | modelSelection: { | 896 | modelSelection: { |
| ... | @@ -909,8 +909,8 @@ describe("OrchestrationEngine", () => { | ... | @@ -909,8 +909,8 @@ describe("OrchestrationEngine", () => { |
| 909 | runtime.runPromise( | 909 | runtime.runPromise( |
| 910 | engine.dispatch({ | 910 | engine.dispatch({ |
| 911 | type: "thread.meta.update", | 911 | type: "thread.meta.update", |
| 912 | commandId: CommandId.makeUnsafe("cmd-thread-meta-sync-fail"), | 912 | commandId: CommandId.make("cmd-thread-meta-sync-fail"), |
| 913 | threadId: ThreadId.makeUnsafe("thread-sync"), | 913 | threadId: ThreadId.make("thread-sync"), |
| 914 | title: "sync-after-failed-projection", | 914 | title: "sync-after-failed-projection", |
| 915 | }), | 915 | }), |
| 916 | ), | 916 | ), |
| ... | @@ -934,8 +934,8 @@ describe("OrchestrationEngine", () => { | ... | @@ -934,8 +934,8 @@ describe("OrchestrationEngine", () => { |
| 934 | system.run( | 934 | system.run( |
| 935 | engine.dispatch({ | 935 | engine.dispatch({ |
| 936 | type: "thread.turn.start", | 936 | type: "thread.turn.start", |
| 937 | commandId: CommandId.makeUnsafe("cmd-invariant-missing-thread"), | 937 | commandId: CommandId.make("cmd-invariant-missing-thread"), |
| 938 | threadId: ThreadId.makeUnsafe("thread-missing"), | 938 | threadId: ThreadId.make("thread-missing"), |
| 939 | message: { | 939 | message: { |
| 940 | messageId: asMessageId("msg-missing"), | 940 | messageId: asMessageId("msg-missing"), |
| 941 | role: "user", | 941 | role: "user", |
| ... | @@ -960,7 +960,7 @@ describe("OrchestrationEngine", () => { | ... | @@ -960,7 +960,7 @@ describe("OrchestrationEngine", () => { |
| 960 | await system.run( | 960 | await system.run( |
| 961 | engine.dispatch({ | 961 | engine.dispatch({ |
| 962 | type: "project.create", | 962 | type: "project.create", |
| 963 | commandId: CommandId.makeUnsafe("cmd-project-duplicate-create"), | 963 | commandId: CommandId.make("cmd-project-duplicate-create"), |
| 964 | projectId: asProjectId("project-duplicate"), | 964 | projectId: asProjectId("project-duplicate"), |
| 965 | title: "Duplicate Project", | 965 | title: "Duplicate Project", |
| 966 | workspaceRoot: "/tmp/project-duplicate", | 966 | workspaceRoot: "/tmp/project-duplicate", |
| ... | @@ -975,8 +975,8 @@ describe("OrchestrationEngine", () => { | ... | @@ -975,8 +975,8 @@ describe("OrchestrationEngine", () => { |
| 975 | await system.run( | 975 | await system.run( |
| 976 | engine.dispatch({ | 976 | engine.dispatch({ |
| 977 | type: "thread.create", | 977 | type: "thread.create", |
| 978 | commandId: CommandId.makeUnsafe("cmd-thread-duplicate-1"), | 978 | commandId: CommandId.make("cmd-thread-duplicate-1"), |
| 979 | threadId: ThreadId.makeUnsafe("thread-duplicate"), | 979 | threadId: ThreadId.make("thread-duplicate"), |
| 980 | projectId: asProjectId("project-duplicate"), | 980 | projectId: asProjectId("project-duplicate"), |
| 981 | title: "duplicate", | 981 | title: "duplicate", |
| 982 | modelSelection: { | 982 | modelSelection: { |
| ... | @@ -995,8 +995,8 @@ describe("OrchestrationEngine", () => { | ... | @@ -995,8 +995,8 @@ describe("OrchestrationEngine", () => { |
| 995 | system.run( | 995 | system.run( |
| 996 | engine.dispatch({ | 996 | engine.dispatch({ |
| 997 | type: "thread.create", | 997 | type: "thread.create", |
| 998 | commandId: CommandId.makeUnsafe("cmd-thread-duplicate-2"), | 998 | commandId: CommandId.make("cmd-thread-duplicate-2"), |
| 999 | threadId: ThreadId.makeUnsafe("thread-duplicate"), | 999 | threadId: ThreadId.make("thread-duplicate"), |
| 1000 | projectId: asProjectId("project-duplicate"), | 1000 | projectId: asProjectId("project-duplicate"), |
| 1001 | title: "duplicate", | 1001 | title: "duplicate", |
| 1002 | modelSelection: { | 1002 | modelSelection: { |
apps/server/src/orchestration/Layers/ProjectionPipeline.test.ts+302-302| ... | @@ -58,16 +58,16 @@ it.layer(BaseTestLayer)("OrchestrationProjectionPipeline", (it) => { | ... | @@ -58,16 +58,16 @@ it.layer(BaseTestLayer)("OrchestrationProjectionPipeline", (it) => { |
| 58 | 58 | ||
| 59 | yield* eventStore.append({ | 59 | yield* eventStore.append({ |
| 60 | type: "project.created", | 60 | type: "project.created", |
| 61 | eventId: EventId.makeUnsafe("evt-1"), | 61 | eventId: EventId.make("evt-1"), |
| 62 | aggregateKind: "project", | 62 | aggregateKind: "project", |
| 63 | aggregateId: ProjectId.makeUnsafe("project-1"), | 63 | aggregateId: ProjectId.make("project-1"), |
| 64 | occurredAt: now, | 64 | occurredAt: now, |
| 65 | commandId: CommandId.makeUnsafe("cmd-1"), | 65 | commandId: CommandId.make("cmd-1"), |
| 66 | causationEventId: null, | 66 | causationEventId: null, |
| 67 | correlationId: CommandId.makeUnsafe("cmd-1"), | 67 | correlationId: CommandId.make("cmd-1"), |
| 68 | metadata: {}, | 68 | metadata: {}, |
| 69 | payload: { | 69 | payload: { |
| 70 | projectId: ProjectId.makeUnsafe("project-1"), | 70 | projectId: ProjectId.make("project-1"), |
| 71 | title: "Project 1", | 71 | title: "Project 1", |
| 72 | workspaceRoot: "/tmp/project-1", | 72 | workspaceRoot: "/tmp/project-1", |
| 73 | defaultModelSelection: null, | 73 | defaultModelSelection: null, |
| ... | @@ -79,17 +79,17 @@ it.layer(BaseTestLayer)("OrchestrationProjectionPipeline", (it) => { | ... | @@ -79,17 +79,17 @@ it.layer(BaseTestLayer)("OrchestrationProjectionPipeline", (it) => { |
| 79 | 79 | ||
| 80 | yield* eventStore.append({ | 80 | yield* eventStore.append({ |
| 81 | type: "thread.created", | 81 | type: "thread.created", |
| 82 | eventId: EventId.makeUnsafe("evt-2"), | 82 | eventId: EventId.make("evt-2"), |
| 83 | aggregateKind: "thread", | 83 | aggregateKind: "thread", |
| 84 | aggregateId: ThreadId.makeUnsafe("thread-1"), | 84 | aggregateId: ThreadId.make("thread-1"), |
| 85 | occurredAt: now, | 85 | occurredAt: now, |
| 86 | commandId: CommandId.makeUnsafe("cmd-2"), | 86 | commandId: CommandId.make("cmd-2"), |
| 87 | causationEventId: null, | 87 | causationEventId: null, |
| 88 | correlationId: CommandId.makeUnsafe("cmd-2"), | 88 | correlationId: CommandId.make("cmd-2"), |
| 89 | metadata: {}, | 89 | metadata: {}, |
| 90 | payload: { | 90 | payload: { |
| 91 | threadId: ThreadId.makeUnsafe("thread-1"), | 91 | threadId: ThreadId.make("thread-1"), |
| 92 | projectId: ProjectId.makeUnsafe("project-1"), | 92 | projectId: ProjectId.make("project-1"), |
| 93 | title: "Thread 1", | 93 | title: "Thread 1", |
| 94 | modelSelection: { | 94 | modelSelection: { |
| 95 | provider: "codex", | 95 | provider: "codex", |
| ... | @@ -105,17 +105,17 @@ it.layer(BaseTestLayer)("OrchestrationProjectionPipeline", (it) => { | ... | @@ -105,17 +105,17 @@ it.layer(BaseTestLayer)("OrchestrationProjectionPipeline", (it) => { |
| 105 | 105 | ||
| 106 | yield* eventStore.append({ | 106 | yield* eventStore.append({ |
| 107 | type: "thread.message-sent", | 107 | type: "thread.message-sent", |
| 108 | eventId: EventId.makeUnsafe("evt-3"), | 108 | eventId: EventId.make("evt-3"), |
| 109 | aggregateKind: "thread", | 109 | aggregateKind: "thread", |
| 110 | aggregateId: ThreadId.makeUnsafe("thread-1"), | 110 | aggregateId: ThreadId.make("thread-1"), |
| 111 | occurredAt: now, | 111 | occurredAt: now, |
| 112 | commandId: CommandId.makeUnsafe("cmd-3"), | 112 | commandId: CommandId.make("cmd-3"), |
| 113 | causationEventId: null, | 113 | causationEventId: null, |
| 114 | correlationId: CommandId.makeUnsafe("cmd-3"), | 114 | correlationId: CommandId.make("cmd-3"), |
| 115 | metadata: {}, | 115 | metadata: {}, |
| 116 | payload: { | 116 | payload: { |
| 117 | threadId: ThreadId.makeUnsafe("thread-1"), | 117 | threadId: ThreadId.make("thread-1"), |
| 118 | messageId: MessageId.makeUnsafe("message-1"), | 118 | messageId: MessageId.make("message-1"), |
| 119 | role: "assistant", | 119 | role: "assistant", |
| 120 | text: "hello", | 120 | text: "hello", |
| 121 | turnId: null, | 121 | turnId: null, |
| ... | @@ -183,17 +183,17 @@ it.layer(Layer.fresh(makeProjectionPipelinePrefixedTestLayer("t3-base-")))( | ... | @@ -183,17 +183,17 @@ it.layer(Layer.fresh(makeProjectionPipelinePrefixedTestLayer("t3-base-")))( |
| 183 | 183 | ||
| 184 | yield* eventStore.append({ | 184 | yield* eventStore.append({ |
| 185 | type: "thread.message-sent", | 185 | type: "thread.message-sent", |
| 186 | eventId: EventId.makeUnsafe("evt-attachments"), | 186 | eventId: EventId.make("evt-attachments"), |
| 187 | aggregateKind: "thread", | 187 | aggregateKind: "thread", |
| 188 | aggregateId: ThreadId.makeUnsafe("thread-attachments"), | 188 | aggregateId: ThreadId.make("thread-attachments"), |
| 189 | occurredAt: now, | 189 | occurredAt: now, |
| 190 | commandId: CommandId.makeUnsafe("cmd-attachments"), | 190 | commandId: CommandId.make("cmd-attachments"), |
| 191 | causationEventId: null, | 191 | causationEventId: null, |
| 192 | correlationId: CommandId.makeUnsafe("cmd-attachments"), | 192 | correlationId: CommandId.make("cmd-attachments"), |
| 193 | metadata: {}, | 193 | metadata: {}, |
| 194 | payload: { | 194 | payload: { |
| 195 | threadId: ThreadId.makeUnsafe("thread-attachments"), | 195 | threadId: ThreadId.make("thread-attachments"), |
| 196 | messageId: MessageId.makeUnsafe("message-attachments"), | 196 | messageId: MessageId.make("message-attachments"), |
| 197 | role: "user", | 197 | role: "user", |
| 198 | text: "Inspect this", | 198 | text: "Inspect this", |
| 199 | attachments: [ | 199 | attachments: [ |
| ... | @@ -249,17 +249,17 @@ it.layer(Layer.fresh(makeProjectionPipelinePrefixedTestLayer("t3-projection-atta | ... | @@ -249,17 +249,17 @@ it.layer(Layer.fresh(makeProjectionPipelinePrefixedTestLayer("t3-projection-atta |
| 249 | 249 | ||
| 250 | yield* eventStore.append({ | 250 | yield* eventStore.append({ |
| 251 | type: "thread.message-sent", | 251 | type: "thread.message-sent", |
| 252 | eventId: EventId.makeUnsafe("evt-attachments-safe"), | 252 | eventId: EventId.make("evt-attachments-safe"), |
| 253 | aggregateKind: "thread", | 253 | aggregateKind: "thread", |
| 254 | aggregateId: ThreadId.makeUnsafe("thread-attachments-safe"), | 254 | aggregateId: ThreadId.make("thread-attachments-safe"), |
| 255 | occurredAt: now, | 255 | occurredAt: now, |
| 256 | commandId: CommandId.makeUnsafe("cmd-attachments-safe"), | 256 | commandId: CommandId.make("cmd-attachments-safe"), |
| 257 | causationEventId: null, | 257 | causationEventId: null, |
| 258 | correlationId: CommandId.makeUnsafe("cmd-attachments-safe"), | 258 | correlationId: CommandId.make("cmd-attachments-safe"), |
| 259 | metadata: {}, | 259 | metadata: {}, |
| 260 | payload: { | 260 | payload: { |
| 261 | threadId: ThreadId.makeUnsafe("thread-attachments-safe"), | 261 | threadId: ThreadId.make("thread-attachments-safe"), |
| 262 | messageId: MessageId.makeUnsafe("message-attachments-safe"), | 262 | messageId: MessageId.make("message-attachments-safe"), |
| 263 | role: "user", | 263 | role: "user", |
| 264 | text: "Inspect this", | 264 | text: "Inspect this", |
| 265 | attachments: [ | 265 | attachments: [ |
| ... | @@ -330,16 +330,16 @@ it.layer(BaseTestLayer)("OrchestrationProjectionPipeline", (it) => { | ... | @@ -330,16 +330,16 @@ it.layer(BaseTestLayer)("OrchestrationProjectionPipeline", (it) => { |
| 330 | 330 | ||
| 331 | yield* eventStore.append({ | 331 | yield* eventStore.append({ |
| 332 | type: "project.created", | 332 | type: "project.created", |
| 333 | eventId: EventId.makeUnsafe("evt-clear-attachments-1"), | 333 | eventId: EventId.make("evt-clear-attachments-1"), |
| 334 | aggregateKind: "project", | 334 | aggregateKind: "project", |
| 335 | aggregateId: ProjectId.makeUnsafe("project-clear-attachments"), | 335 | aggregateId: ProjectId.make("project-clear-attachments"), |
| 336 | occurredAt: now, | 336 | occurredAt: now, |
| 337 | commandId: CommandId.makeUnsafe("cmd-clear-attachments-1"), | 337 | commandId: CommandId.make("cmd-clear-attachments-1"), |
| 338 | causationEventId: null, | 338 | causationEventId: null, |
| 339 | correlationId: CommandId.makeUnsafe("cmd-clear-attachments-1"), | 339 | correlationId: CommandId.make("cmd-clear-attachments-1"), |
| 340 | metadata: {}, | 340 | metadata: {}, |
| 341 | payload: { | 341 | payload: { |
| 342 | projectId: ProjectId.makeUnsafe("project-clear-attachments"), | 342 | projectId: ProjectId.make("project-clear-attachments"), |
| 343 | title: "Project Clear Attachments", | 343 | title: "Project Clear Attachments", |
| 344 | workspaceRoot: "/tmp/project-clear-attachments", | 344 | workspaceRoot: "/tmp/project-clear-attachments", |
| 345 | defaultModelSelection: null, | 345 | defaultModelSelection: null, |
| ... | @@ -351,17 +351,17 @@ it.layer(BaseTestLayer)("OrchestrationProjectionPipeline", (it) => { | ... | @@ -351,17 +351,17 @@ it.layer(BaseTestLayer)("OrchestrationProjectionPipeline", (it) => { |
| 351 | 351 | ||
| 352 | yield* eventStore.append({ | 352 | yield* eventStore.append({ |
| 353 | type: "thread.created", | 353 | type: "thread.created", |
| 354 | eventId: EventId.makeUnsafe("evt-clear-attachments-2"), | 354 | eventId: EventId.make("evt-clear-attachments-2"), |
| 355 | aggregateKind: "thread", | 355 | aggregateKind: "thread", |
| 356 | aggregateId: ThreadId.makeUnsafe("thread-clear-attachments"), | 356 | aggregateId: ThreadId.make("thread-clear-attachments"), |
| 357 | occurredAt: now, | 357 | occurredAt: now, |
| 358 | commandId: CommandId.makeUnsafe("cmd-clear-attachments-2"), | 358 | commandId: CommandId.make("cmd-clear-attachments-2"), |
| 359 | causationEventId: null, | 359 | causationEventId: null, |
| 360 | correlationId: CommandId.makeUnsafe("cmd-clear-attachments-2"), | 360 | correlationId: CommandId.make("cmd-clear-attachments-2"), |
| 361 | metadata: {}, | 361 | metadata: {}, |
| 362 | payload: { | 362 | payload: { |
| 363 | threadId: ThreadId.makeUnsafe("thread-clear-attachments"), | 363 | threadId: ThreadId.make("thread-clear-attachments"), |
| 364 | projectId: ProjectId.makeUnsafe("project-clear-attachments"), | 364 | projectId: ProjectId.make("project-clear-attachments"), |
| 365 | title: "Thread Clear Attachments", | 365 | title: "Thread Clear Attachments", |
| 366 | modelSelection: { | 366 | modelSelection: { |
| 367 | provider: "codex", | 367 | provider: "codex", |
| ... | @@ -377,17 +377,17 @@ it.layer(BaseTestLayer)("OrchestrationProjectionPipeline", (it) => { | ... | @@ -377,17 +377,17 @@ it.layer(BaseTestLayer)("OrchestrationProjectionPipeline", (it) => { |
| 377 | 377 | ||
| 378 | yield* eventStore.append({ | 378 | yield* eventStore.append({ |
| 379 | type: "thread.message-sent", | 379 | type: "thread.message-sent", |
| 380 | eventId: EventId.makeUnsafe("evt-clear-attachments-3"), | 380 | eventId: EventId.make("evt-clear-attachments-3"), |
| 381 | aggregateKind: "thread", | 381 | aggregateKind: "thread", |
| 382 | aggregateId: ThreadId.makeUnsafe("thread-clear-attachments"), | 382 | aggregateId: ThreadId.make("thread-clear-attachments"), |
| 383 | occurredAt: now, | 383 | occurredAt: now, |
| 384 | commandId: CommandId.makeUnsafe("cmd-clear-attachments-3"), | 384 | commandId: CommandId.make("cmd-clear-attachments-3"), |
| 385 | causationEventId: null, | 385 | causationEventId: null, |
| 386 | correlationId: CommandId.makeUnsafe("cmd-clear-attachments-3"), | 386 | correlationId: CommandId.make("cmd-clear-attachments-3"), |
| 387 | metadata: {}, | 387 | metadata: {}, |
| 388 | payload: { | 388 | payload: { |
| 389 | threadId: ThreadId.makeUnsafe("thread-clear-attachments"), | 389 | threadId: ThreadId.make("thread-clear-attachments"), |
| 390 | messageId: MessageId.makeUnsafe("message-clear-attachments"), | 390 | messageId: MessageId.make("message-clear-attachments"), |
| 391 | role: "user", | 391 | role: "user", |
| 392 | text: "Has attachments", | 392 | text: "Has attachments", |
| 393 | attachments: [ | 393 | attachments: [ |
| ... | @@ -408,17 +408,17 @@ it.layer(BaseTestLayer)("OrchestrationProjectionPipeline", (it) => { | ... | @@ -408,17 +408,17 @@ it.layer(BaseTestLayer)("OrchestrationProjectionPipeline", (it) => { |
| 408 | 408 | ||
| 409 | yield* eventStore.append({ | 409 | yield* eventStore.append({ |
| 410 | type: "thread.message-sent", | 410 | type: "thread.message-sent", |
| 411 | eventId: EventId.makeUnsafe("evt-clear-attachments-4"), | 411 | eventId: EventId.make("evt-clear-attachments-4"), |
| 412 | aggregateKind: "thread", | 412 | aggregateKind: "thread", |
| 413 | aggregateId: ThreadId.makeUnsafe("thread-clear-attachments"), | 413 | aggregateId: ThreadId.make("thread-clear-attachments"), |
| 414 | occurredAt: later, | 414 | occurredAt: later, |
| 415 | commandId: CommandId.makeUnsafe("cmd-clear-attachments-4"), | 415 | commandId: CommandId.make("cmd-clear-attachments-4"), |
| 416 | causationEventId: null, | 416 | causationEventId: null, |
| 417 | correlationId: CommandId.makeUnsafe("cmd-clear-attachments-4"), | 417 | correlationId: CommandId.make("cmd-clear-attachments-4"), |
| 418 | metadata: {}, | 418 | metadata: {}, |
| 419 | payload: { | 419 | payload: { |
| 420 | threadId: ThreadId.makeUnsafe("thread-clear-attachments"), | 420 | threadId: ThreadId.make("thread-clear-attachments"), |
| 421 | messageId: MessageId.makeUnsafe("message-clear-attachments"), | 421 | messageId: MessageId.make("message-clear-attachments"), |
| 422 | role: "user", | 422 | role: "user", |
| 423 | text: "", | 423 | text: "", |
| 424 | attachments: [], | 424 | attachments: [], |
| ... | @@ -458,16 +458,16 @@ it.layer( | ... | @@ -458,16 +458,16 @@ it.layer( |
| 458 | 458 | ||
| 459 | yield* eventStore.append({ | 459 | yield* eventStore.append({ |
| 460 | type: "project.created", | 460 | type: "project.created", |
| 461 | eventId: EventId.makeUnsafe("evt-overwrite-1"), | 461 | eventId: EventId.make("evt-overwrite-1"), |
| 462 | aggregateKind: "project", | 462 | aggregateKind: "project", |
| 463 | aggregateId: ProjectId.makeUnsafe("project-overwrite"), | 463 | aggregateId: ProjectId.make("project-overwrite"), |
| 464 | occurredAt: now, | 464 | occurredAt: now, |
| 465 | commandId: CommandId.makeUnsafe("cmd-overwrite-1"), | 465 | commandId: CommandId.make("cmd-overwrite-1"), |
| 466 | causationEventId: null, | 466 | causationEventId: null, |
| 467 | correlationId: CommandId.makeUnsafe("cmd-overwrite-1"), | 467 | correlationId: CommandId.make("cmd-overwrite-1"), |
| 468 | metadata: {}, | 468 | metadata: {}, |
| 469 | payload: { | 469 | payload: { |
| 470 | projectId: ProjectId.makeUnsafe("project-overwrite"), | 470 | projectId: ProjectId.make("project-overwrite"), |
| 471 | title: "Project Overwrite", | 471 | title: "Project Overwrite", |
| 472 | workspaceRoot: "/tmp/project-overwrite", | 472 | workspaceRoot: "/tmp/project-overwrite", |
| 473 | defaultModelSelection: null, | 473 | defaultModelSelection: null, |
| ... | @@ -479,17 +479,17 @@ it.layer( | ... | @@ -479,17 +479,17 @@ it.layer( |
| 479 | 479 | ||
| 480 | yield* eventStore.append({ | 480 | yield* eventStore.append({ |
| 481 | type: "thread.created", | 481 | type: "thread.created", |
| 482 | eventId: EventId.makeUnsafe("evt-overwrite-2"), | 482 | eventId: EventId.make("evt-overwrite-2"), |
| 483 | aggregateKind: "thread", | 483 | aggregateKind: "thread", |
| 484 | aggregateId: ThreadId.makeUnsafe("thread-overwrite"), | 484 | aggregateId: ThreadId.make("thread-overwrite"), |
| 485 | occurredAt: now, | 485 | occurredAt: now, |
| 486 | commandId: CommandId.makeUnsafe("cmd-overwrite-2"), | 486 | commandId: CommandId.make("cmd-overwrite-2"), |
| 487 | causationEventId: null, | 487 | causationEventId: null, |
| 488 | correlationId: CommandId.makeUnsafe("cmd-overwrite-2"), | 488 | correlationId: CommandId.make("cmd-overwrite-2"), |
| 489 | metadata: {}, | 489 | metadata: {}, |
| 490 | payload: { | 490 | payload: { |
| 491 | threadId: ThreadId.makeUnsafe("thread-overwrite"), | 491 | threadId: ThreadId.make("thread-overwrite"), |
| 492 | projectId: ProjectId.makeUnsafe("project-overwrite"), | 492 | projectId: ProjectId.make("project-overwrite"), |
| 493 | title: "Thread Overwrite", | 493 | title: "Thread Overwrite", |
| 494 | modelSelection: { | 494 | modelSelection: { |
| 495 | provider: "codex", | 495 | provider: "codex", |
| ... | @@ -505,17 +505,17 @@ it.layer( | ... | @@ -505,17 +505,17 @@ it.layer( |
| 505 | 505 | ||
| 506 | yield* eventStore.append({ | 506 | yield* eventStore.append({ |
| 507 | type: "thread.message-sent", | 507 | type: "thread.message-sent", |
| 508 | eventId: EventId.makeUnsafe("evt-overwrite-3"), | 508 | eventId: EventId.make("evt-overwrite-3"), |
| 509 | aggregateKind: "thread", | 509 | aggregateKind: "thread", |
| 510 | aggregateId: ThreadId.makeUnsafe("thread-overwrite"), | 510 | aggregateId: ThreadId.make("thread-overwrite"), |
| 511 | occurredAt: now, | 511 | occurredAt: now, |
| 512 | commandId: CommandId.makeUnsafe("cmd-overwrite-3"), | 512 | commandId: CommandId.make("cmd-overwrite-3"), |
| 513 | causationEventId: null, | 513 | causationEventId: null, |
| 514 | correlationId: CommandId.makeUnsafe("cmd-overwrite-3"), | 514 | correlationId: CommandId.make("cmd-overwrite-3"), |
| 515 | metadata: {}, | 515 | metadata: {}, |
| 516 | payload: { | 516 | payload: { |
| 517 | threadId: ThreadId.makeUnsafe("thread-overwrite"), | 517 | threadId: ThreadId.make("thread-overwrite"), |
| 518 | messageId: MessageId.makeUnsafe("message-overwrite"), | 518 | messageId: MessageId.make("message-overwrite"), |
| 519 | role: "user", | 519 | role: "user", |
| 520 | text: "first image", | 520 | text: "first image", |
| 521 | attachments: [ | 521 | attachments: [ |
| ... | @@ -536,17 +536,17 @@ it.layer( | ... | @@ -536,17 +536,17 @@ it.layer( |
| 536 | 536 | ||
| 537 | yield* eventStore.append({ | 537 | yield* eventStore.append({ |
| 538 | type: "thread.message-sent", | 538 | type: "thread.message-sent", |
| 539 | eventId: EventId.makeUnsafe("evt-overwrite-4"), | 539 | eventId: EventId.make("evt-overwrite-4"), |
| 540 | aggregateKind: "thread", | 540 | aggregateKind: "thread", |
| 541 | aggregateId: ThreadId.makeUnsafe("thread-overwrite"), | 541 | aggregateId: ThreadId.make("thread-overwrite"), |
| 542 | occurredAt: later, | 542 | occurredAt: later, |
| 543 | commandId: CommandId.makeUnsafe("cmd-overwrite-4"), | 543 | commandId: CommandId.make("cmd-overwrite-4"), |
| 544 | causationEventId: null, | 544 | causationEventId: null, |
| 545 | correlationId: CommandId.makeUnsafe("cmd-overwrite-4"), | 545 | correlationId: CommandId.make("cmd-overwrite-4"), |
| 546 | metadata: {}, | 546 | metadata: {}, |
| 547 | payload: { | 547 | payload: { |
| 548 | threadId: ThreadId.makeUnsafe("thread-overwrite"), | 548 | threadId: ThreadId.make("thread-overwrite"), |
| 549 | messageId: MessageId.makeUnsafe("message-overwrite"), | 549 | messageId: MessageId.make("message-overwrite"), |
| 550 | role: "user", | 550 | role: "user", |
| 551 | text: "", | 551 | text: "", |
| 552 | attachments: [ | 552 | attachments: [ |
| ... | @@ -606,16 +606,16 @@ it.layer( | ... | @@ -606,16 +606,16 @@ it.layer( |
| 606 | 606 | ||
| 607 | yield* appendAndProject({ | 607 | yield* appendAndProject({ |
| 608 | type: "project.created", | 608 | type: "project.created", |
| 609 | eventId: EventId.makeUnsafe("evt-rollback-1"), | 609 | eventId: EventId.make("evt-rollback-1"), |
| 610 | aggregateKind: "project", | 610 | aggregateKind: "project", |
| 611 | aggregateId: ProjectId.makeUnsafe("project-rollback"), | 611 | aggregateId: ProjectId.make("project-rollback"), |
| 612 | occurredAt: now, | 612 | occurredAt: now, |
| 613 | commandId: CommandId.makeUnsafe("cmd-rollback-1"), | 613 | commandId: CommandId.make("cmd-rollback-1"), |
| 614 | causationEventId: null, | 614 | causationEventId: null, |
| 615 | correlationId: CorrelationId.makeUnsafe("cmd-rollback-1"), | 615 | correlationId: CorrelationId.make("cmd-rollback-1"), |
| 616 | metadata: {}, | 616 | metadata: {}, |
| 617 | payload: { | 617 | payload: { |
| 618 | projectId: ProjectId.makeUnsafe("project-rollback"), | 618 | projectId: ProjectId.make("project-rollback"), |
| 619 | title: "Project Rollback", | 619 | title: "Project Rollback", |
| 620 | workspaceRoot: "/tmp/project-rollback", | 620 | workspaceRoot: "/tmp/project-rollback", |
| 621 | defaultModelSelection: null, | 621 | defaultModelSelection: null, |
| ... | @@ -627,17 +627,17 @@ it.layer( | ... | @@ -627,17 +627,17 @@ it.layer( |
| 627 | 627 | ||
| 628 | yield* appendAndProject({ | 628 | yield* appendAndProject({ |
| 629 | type: "thread.created", | 629 | type: "thread.created", |
| 630 | eventId: EventId.makeUnsafe("evt-rollback-2"), | 630 | eventId: EventId.make("evt-rollback-2"), |
| 631 | aggregateKind: "thread", | 631 | aggregateKind: "thread", |
| 632 | aggregateId: ThreadId.makeUnsafe("thread-rollback"), | 632 | aggregateId: ThreadId.make("thread-rollback"), |
| 633 | occurredAt: now, | 633 | occurredAt: now, |
| 634 | commandId: CommandId.makeUnsafe("cmd-rollback-2"), | 634 | commandId: CommandId.make("cmd-rollback-2"), |
| 635 | causationEventId: null, | 635 | causationEventId: null, |
| 636 | correlationId: CorrelationId.makeUnsafe("cmd-rollback-2"), | 636 | correlationId: CorrelationId.make("cmd-rollback-2"), |
| 637 | metadata: {}, | 637 | metadata: {}, |
| 638 | payload: { | 638 | payload: { |
| 639 | threadId: ThreadId.makeUnsafe("thread-rollback"), | 639 | threadId: ThreadId.make("thread-rollback"), |
| 640 | projectId: ProjectId.makeUnsafe("project-rollback"), | 640 | projectId: ProjectId.make("project-rollback"), |
| 641 | title: "Thread Rollback", | 641 | title: "Thread Rollback", |
| 642 | modelSelection: { | 642 | modelSelection: { |
| 643 | provider: "codex", | 643 | provider: "codex", |
| ... | @@ -663,17 +663,17 @@ it.layer( | ... | @@ -663,17 +663,17 @@ it.layer( |
| 663 | const result = yield* Effect.result( | 663 | const result = yield* Effect.result( |
| 664 | appendAndProject({ | 664 | appendAndProject({ |
| 665 | type: "thread.message-sent", | 665 | type: "thread.message-sent", |
| 666 | eventId: EventId.makeUnsafe("evt-rollback-3"), | 666 | eventId: EventId.make("evt-rollback-3"), |
| 667 | aggregateKind: "thread", | 667 | aggregateKind: "thread", |
| 668 | aggregateId: ThreadId.makeUnsafe("thread-rollback"), | 668 | aggregateId: ThreadId.make("thread-rollback"), |
| 669 | occurredAt: now, | 669 | occurredAt: now, |
| 670 | commandId: CommandId.makeUnsafe("cmd-rollback-3"), | 670 | commandId: CommandId.make("cmd-rollback-3"), |
| 671 | causationEventId: null, | 671 | causationEventId: null, |
| 672 | correlationId: CorrelationId.makeUnsafe("cmd-rollback-3"), | 672 | correlationId: CorrelationId.make("cmd-rollback-3"), |
| 673 | metadata: {}, | 673 | metadata: {}, |
| 674 | payload: { | 674 | payload: { |
| 675 | threadId: ThreadId.makeUnsafe("thread-rollback"), | 675 | threadId: ThreadId.make("thread-rollback"), |
| 676 | messageId: MessageId.makeUnsafe("message-rollback"), | 676 | messageId: MessageId.make("message-rollback"), |
| 677 | role: "user", | 677 | role: "user", |
| 678 | text: "Rollback me", | 678 | text: "Rollback me", |
| 679 | attachments: [ | 679 | attachments: [ |
| ... | @@ -722,7 +722,7 @@ it.layer( | ... | @@ -722,7 +722,7 @@ it.layer( |
| 722 | const eventStore = yield* OrchestrationEventStore; | 722 | const eventStore = yield* OrchestrationEventStore; |
| 723 | const { attachmentsDir } = yield* ServerConfig; | 723 | const { attachmentsDir } = yield* ServerConfig; |
| 724 | const now = new Date().toISOString(); | 724 | const now = new Date().toISOString(); |
| 725 | const threadId = ThreadId.makeUnsafe("Thread Revert.Files"); | 725 | const threadId = ThreadId.make("Thread Revert.Files"); |
| 726 | const keepAttachmentId = "thread-revert-files-00000000-0000-4000-8000-000000000001"; | 726 | const keepAttachmentId = "thread-revert-files-00000000-0000-4000-8000-000000000001"; |
| 727 | const removeAttachmentId = "thread-revert-files-00000000-0000-4000-8000-000000000002"; | 727 | const removeAttachmentId = "thread-revert-files-00000000-0000-4000-8000-000000000002"; |
| 728 | const otherThreadAttachmentId = | 728 | const otherThreadAttachmentId = |
| ... | @@ -735,16 +735,16 @@ it.layer( | ... | @@ -735,16 +735,16 @@ it.layer( |
| 735 | 735 | ||
| 736 | yield* appendAndProject({ | 736 | yield* appendAndProject({ |
| 737 | type: "project.created", | 737 | type: "project.created", |
| 738 | eventId: EventId.makeUnsafe("evt-revert-files-1"), | 738 | eventId: EventId.make("evt-revert-files-1"), |
| 739 | aggregateKind: "project", | 739 | aggregateKind: "project", |
| 740 | aggregateId: ProjectId.makeUnsafe("project-revert-files"), | 740 | aggregateId: ProjectId.make("project-revert-files"), |
| 741 | occurredAt: now, | 741 | occurredAt: now, |
| 742 | commandId: CommandId.makeUnsafe("cmd-revert-files-1"), | 742 | commandId: CommandId.make("cmd-revert-files-1"), |
| 743 | causationEventId: null, | 743 | causationEventId: null, |
| 744 | correlationId: CorrelationId.makeUnsafe("cmd-revert-files-1"), | 744 | correlationId: CorrelationId.make("cmd-revert-files-1"), |
| 745 | metadata: {}, | 745 | metadata: {}, |
| 746 | payload: { | 746 | payload: { |
| 747 | projectId: ProjectId.makeUnsafe("project-revert-files"), | 747 | projectId: ProjectId.make("project-revert-files"), |
| 748 | title: "Project Revert Files", | 748 | title: "Project Revert Files", |
| 749 | workspaceRoot: "/tmp/project-revert-files", | 749 | workspaceRoot: "/tmp/project-revert-files", |
| 750 | defaultModelSelection: null, | 750 | defaultModelSelection: null, |
| ... | @@ -756,17 +756,17 @@ it.layer( | ... | @@ -756,17 +756,17 @@ it.layer( |
| 756 | 756 | ||
| 757 | yield* appendAndProject({ | 757 | yield* appendAndProject({ |
| 758 | type: "thread.created", | 758 | type: "thread.created", |
| 759 | eventId: EventId.makeUnsafe("evt-revert-files-2"), | 759 | eventId: EventId.make("evt-revert-files-2"), |
| 760 | aggregateKind: "thread", | 760 | aggregateKind: "thread", |
| 761 | aggregateId: threadId, | 761 | aggregateId: threadId, |
| 762 | occurredAt: now, | 762 | occurredAt: now, |
| 763 | commandId: CommandId.makeUnsafe("cmd-revert-files-2"), | 763 | commandId: CommandId.make("cmd-revert-files-2"), |
| 764 | causationEventId: null, | 764 | causationEventId: null, |
| 765 | correlationId: CorrelationId.makeUnsafe("cmd-revert-files-2"), | 765 | correlationId: CorrelationId.make("cmd-revert-files-2"), |
| 766 | metadata: {}, | 766 | metadata: {}, |
| 767 | payload: { | 767 | payload: { |
| 768 | threadId, | 768 | threadId, |
| 769 | projectId: ProjectId.makeUnsafe("project-revert-files"), | 769 | projectId: ProjectId.make("project-revert-files"), |
| 770 | title: "Thread Revert Files", | 770 | title: "Thread Revert Files", |
| 771 | modelSelection: { | 771 | modelSelection: { |
| 772 | provider: "codex", | 772 | provider: "codex", |
| ... | @@ -782,39 +782,39 @@ it.layer( | ... | @@ -782,39 +782,39 @@ it.layer( |
| 782 | 782 | ||
| 783 | yield* appendAndProject({ | 783 | yield* appendAndProject({ |
| 784 | type: "thread.turn-diff-completed", | 784 | type: "thread.turn-diff-completed", |
| 785 | eventId: EventId.makeUnsafe("evt-revert-files-3"), | 785 | eventId: EventId.make("evt-revert-files-3"), |
| 786 | aggregateKind: "thread", | 786 | aggregateKind: "thread", |
| 787 | aggregateId: threadId, | 787 | aggregateId: threadId, |
| 788 | occurredAt: now, | 788 | occurredAt: now, |
| 789 | commandId: CommandId.makeUnsafe("cmd-revert-files-3"), | 789 | commandId: CommandId.make("cmd-revert-files-3"), |
| 790 | causationEventId: null, | 790 | causationEventId: null, |
| 791 | correlationId: CorrelationId.makeUnsafe("cmd-revert-files-3"), | 791 | correlationId: CorrelationId.make("cmd-revert-files-3"), |
| 792 | metadata: {}, | 792 | metadata: {}, |
| 793 | payload: { | 793 | payload: { |
| 794 | threadId, | 794 | threadId, |
| 795 | turnId: TurnId.makeUnsafe("turn-keep"), | 795 | turnId: TurnId.make("turn-keep"), |
| 796 | checkpointTurnCount: 1, | 796 | checkpointTurnCount: 1, |
| 797 | checkpointRef: CheckpointRef.makeUnsafe("refs/t3/checkpoints/thread-revert-files/turn/1"), | 797 | checkpointRef: CheckpointRef.make("refs/t3/checkpoints/thread-revert-files/turn/1"), |
| 798 | status: "ready", | 798 | status: "ready", |
| 799 | files: [], | 799 | files: [], |
| 800 | assistantMessageId: MessageId.makeUnsafe("message-keep"), | 800 | assistantMessageId: MessageId.make("message-keep"), |
| 801 | completedAt: now, | 801 | completedAt: now, |
| 802 | }, | 802 | }, |
| 803 | }); | 803 | }); |
| 804 | 804 | ||
| 805 | yield* appendAndProject({ | 805 | yield* appendAndProject({ |
| 806 | type: "thread.message-sent", | 806 | type: "thread.message-sent", |
| 807 | eventId: EventId.makeUnsafe("evt-revert-files-4"), | 807 | eventId: EventId.make("evt-revert-files-4"), |
| 808 | aggregateKind: "thread", | 808 | aggregateKind: "thread", |
| 809 | aggregateId: threadId, | 809 | aggregateId: threadId, |
| 810 | occurredAt: now, | 810 | occurredAt: now, |
| 811 | commandId: CommandId.makeUnsafe("cmd-revert-files-4"), | 811 | commandId: CommandId.make("cmd-revert-files-4"), |
| 812 | causationEventId: null, | 812 | causationEventId: null, |
| 813 | correlationId: CorrelationId.makeUnsafe("cmd-revert-files-4"), | 813 | correlationId: CorrelationId.make("cmd-revert-files-4"), |
| 814 | metadata: {}, | 814 | metadata: {}, |
| 815 | payload: { | 815 | payload: { |
| 816 | threadId, | 816 | threadId, |
| 817 | messageId: MessageId.makeUnsafe("message-keep"), | 817 | messageId: MessageId.make("message-keep"), |
| 818 | role: "assistant", | 818 | role: "assistant", |
| 819 | text: "Keep", | 819 | text: "Keep", |
| 820 | attachments: [ | 820 | attachments: [ |
| ... | @@ -826,7 +826,7 @@ it.layer( | ... | @@ -826,7 +826,7 @@ it.layer( |
| 826 | sizeBytes: 5, | 826 | sizeBytes: 5, |
| 827 | }, | 827 | }, |
| 828 | ], | 828 | ], |
| 829 | turnId: TurnId.makeUnsafe("turn-keep"), | 829 | turnId: TurnId.make("turn-keep"), |
| 830 | streaming: false, | 830 | streaming: false, |
| 831 | createdAt: now, | 831 | createdAt: now, |
| 832 | updatedAt: now, | 832 | updatedAt: now, |
| ... | @@ -835,39 +835,39 @@ it.layer( | ... | @@ -835,39 +835,39 @@ it.layer( |
| 835 | 835 | ||
| 836 | yield* appendAndProject({ | 836 | yield* appendAndProject({ |
| 837 | type: "thread.turn-diff-completed", | 837 | type: "thread.turn-diff-completed", |
| 838 | eventId: EventId.makeUnsafe("evt-revert-files-5"), | 838 | eventId: EventId.make("evt-revert-files-5"), |
| 839 | aggregateKind: "thread", | 839 | aggregateKind: "thread", |
| 840 | aggregateId: threadId, | 840 | aggregateId: threadId, |
| 841 | occurredAt: now, | 841 | occurredAt: now, |
| 842 | commandId: CommandId.makeUnsafe("cmd-revert-files-5"), | 842 | commandId: CommandId.make("cmd-revert-files-5"), |
| 843 | causationEventId: null, | 843 | causationEventId: null, |
| 844 | correlationId: CorrelationId.makeUnsafe("cmd-revert-files-5"), | 844 | correlationId: CorrelationId.make("cmd-revert-files-5"), |
| 845 | metadata: {}, | 845 | metadata: {}, |
| 846 | payload: { | 846 | payload: { |
| 847 | threadId, | 847 | threadId, |
| 848 | turnId: TurnId.makeUnsafe("turn-remove"), | 848 | turnId: TurnId.make("turn-remove"), |
| 849 | checkpointTurnCount: 2, | 849 | checkpointTurnCount: 2, |
| 850 | checkpointRef: CheckpointRef.makeUnsafe("refs/t3/checkpoints/thread-revert-files/turn/2"), | 850 | checkpointRef: CheckpointRef.make("refs/t3/checkpoints/thread-revert-files/turn/2"), |
| 851 | status: "ready", | 851 | status: "ready", |
| 852 | files: [], | 852 | files: [], |
| 853 | assistantMessageId: MessageId.makeUnsafe("message-remove"), | 853 | assistantMessageId: MessageId.make("message-remove"), |
| 854 | completedAt: now, | 854 | completedAt: now, |
| 855 | }, | 855 | }, |
| 856 | }); | 856 | }); |
| 857 | 857 | ||
| 858 | yield* appendAndProject({ | 858 | yield* appendAndProject({ |
| 859 | type: "thread.message-sent", | 859 | type: "thread.message-sent", |
| 860 | eventId: EventId.makeUnsafe("evt-revert-files-6"), | 860 | eventId: EventId.make("evt-revert-files-6"), |
| 861 | aggregateKind: "thread", | 861 | aggregateKind: "thread", |
| 862 | aggregateId: threadId, | 862 | aggregateId: threadId, |
| 863 | occurredAt: now, | 863 | occurredAt: now, |
| 864 | commandId: CommandId.makeUnsafe("cmd-revert-files-6"), | 864 | commandId: CommandId.make("cmd-revert-files-6"), |
| 865 | causationEventId: null, | 865 | causationEventId: null, |
| 866 | correlationId: CorrelationId.makeUnsafe("cmd-revert-files-6"), | 866 | correlationId: CorrelationId.make("cmd-revert-files-6"), |
| 867 | metadata: {}, | 867 | metadata: {}, |
| 868 | payload: { | 868 | payload: { |
| 869 | threadId, | 869 | threadId, |
| 870 | messageId: MessageId.makeUnsafe("message-remove"), | 870 | messageId: MessageId.make("message-remove"), |
| 871 | role: "assistant", | 871 | role: "assistant", |
| 872 | text: "Remove", | 872 | text: "Remove", |
| 873 | attachments: [ | 873 | attachments: [ |
| ... | @@ -879,7 +879,7 @@ it.layer( | ... | @@ -879,7 +879,7 @@ it.layer( |
| 879 | sizeBytes: 5, | 879 | sizeBytes: 5, |
| 880 | }, | 880 | }, |
| 881 | ], | 881 | ], |
| 882 | turnId: TurnId.makeUnsafe("turn-remove"), | 882 | turnId: TurnId.make("turn-remove"), |
| 883 | streaming: false, | 883 | streaming: false, |
| 884 | createdAt: now, | 884 | createdAt: now, |
| 885 | updatedAt: now, | 885 | updatedAt: now, |
| ... | @@ -899,13 +899,13 @@ it.layer( | ... | @@ -899,13 +899,13 @@ it.layer( |
| 899 | 899 | ||
| 900 | yield* appendAndProject({ | 900 | yield* appendAndProject({ |
| 901 | type: "thread.reverted", | 901 | type: "thread.reverted", |
| 902 | eventId: EventId.makeUnsafe("evt-revert-files-7"), | 902 | eventId: EventId.make("evt-revert-files-7"), |
| 903 | aggregateKind: "thread", | 903 | aggregateKind: "thread", |
| 904 | aggregateId: threadId, | 904 | aggregateId: threadId, |
| 905 | occurredAt: now, | 905 | occurredAt: now, |
| 906 | commandId: CommandId.makeUnsafe("cmd-revert-files-7"), | 906 | commandId: CommandId.make("cmd-revert-files-7"), |
| 907 | causationEventId: null, | 907 | causationEventId: null, |
| 908 | correlationId: CorrelationId.makeUnsafe("cmd-revert-files-7"), | 908 | correlationId: CorrelationId.make("cmd-revert-files-7"), |
| 909 | metadata: {}, | 909 | metadata: {}, |
| 910 | payload: { | 910 | payload: { |
| 911 | threadId, | 911 | threadId, |
| ... | @@ -931,7 +931,7 @@ it.layer(Layer.fresh(makeProjectionPipelinePrefixedTestLayer("t3-projection-atta | ... | @@ -931,7 +931,7 @@ it.layer(Layer.fresh(makeProjectionPipelinePrefixedTestLayer("t3-projection-atta |
| 931 | const eventStore = yield* OrchestrationEventStore; | 931 | const eventStore = yield* OrchestrationEventStore; |
| 932 | const { attachmentsDir } = yield* ServerConfig; | 932 | const { attachmentsDir } = yield* ServerConfig; |
| 933 | const now = new Date().toISOString(); | 933 | const now = new Date().toISOString(); |
| 934 | const threadId = ThreadId.makeUnsafe("Thread Delete.Files"); | 934 | const threadId = ThreadId.make("Thread Delete.Files"); |
| 935 | const attachmentId = "thread-delete-files-00000000-0000-4000-8000-000000000001"; | 935 | const attachmentId = "thread-delete-files-00000000-0000-4000-8000-000000000001"; |
| 936 | const otherThreadAttachmentId = | 936 | const otherThreadAttachmentId = |
| 937 | "thread-delete-files-extra-00000000-0000-4000-8000-000000000002"; | 937 | "thread-delete-files-extra-00000000-0000-4000-8000-000000000002"; |
| ... | @@ -943,16 +943,16 @@ it.layer(Layer.fresh(makeProjectionPipelinePrefixedTestLayer("t3-projection-atta | ... | @@ -943,16 +943,16 @@ it.layer(Layer.fresh(makeProjectionPipelinePrefixedTestLayer("t3-projection-atta |
| 943 | 943 | ||
| 944 | yield* appendAndProject({ | 944 | yield* appendAndProject({ |
| 945 | type: "project.created", | 945 | type: "project.created", |
| 946 | eventId: EventId.makeUnsafe("evt-delete-files-1"), | 946 | eventId: EventId.make("evt-delete-files-1"), |
| 947 | aggregateKind: "project", | 947 | aggregateKind: "project", |
| 948 | aggregateId: ProjectId.makeUnsafe("project-delete-files"), | 948 | aggregateId: ProjectId.make("project-delete-files"), |
| 949 | occurredAt: now, | 949 | occurredAt: now, |
| 950 | commandId: CommandId.makeUnsafe("cmd-delete-files-1"), | 950 | commandId: CommandId.make("cmd-delete-files-1"), |
| 951 | causationEventId: null, | 951 | causationEventId: null, |
| 952 | correlationId: CorrelationId.makeUnsafe("cmd-delete-files-1"), | 952 | correlationId: CorrelationId.make("cmd-delete-files-1"), |
| 953 | metadata: {}, | 953 | metadata: {}, |
| 954 | payload: { | 954 | payload: { |
| 955 | projectId: ProjectId.makeUnsafe("project-delete-files"), | 955 | projectId: ProjectId.make("project-delete-files"), |
| 956 | title: "Project Delete Files", | 956 | title: "Project Delete Files", |
| 957 | workspaceRoot: "/tmp/project-delete-files", | 957 | workspaceRoot: "/tmp/project-delete-files", |
| 958 | defaultModelSelection: null, | 958 | defaultModelSelection: null, |
| ... | @@ -964,17 +964,17 @@ it.layer(Layer.fresh(makeProjectionPipelinePrefixedTestLayer("t3-projection-atta | ... | @@ -964,17 +964,17 @@ it.layer(Layer.fresh(makeProjectionPipelinePrefixedTestLayer("t3-projection-atta |
| 964 | 964 | ||
| 965 | yield* appendAndProject({ | 965 | yield* appendAndProject({ |
| 966 | type: "thread.created", | 966 | type: "thread.created", |
| 967 | eventId: EventId.makeUnsafe("evt-delete-files-2"), | 967 | eventId: EventId.make("evt-delete-files-2"), |
| 968 | aggregateKind: "thread", | 968 | aggregateKind: "thread", |
| 969 | aggregateId: threadId, | 969 | aggregateId: threadId, |
| 970 | occurredAt: now, | 970 | occurredAt: now, |
| 971 | commandId: CommandId.makeUnsafe("cmd-delete-files-2"), | 971 | commandId: CommandId.make("cmd-delete-files-2"), |
| 972 | causationEventId: null, | 972 | causationEventId: null, |
| 973 | correlationId: CorrelationId.makeUnsafe("cmd-delete-files-2"), | 973 | correlationId: CorrelationId.make("cmd-delete-files-2"), |
| 974 | metadata: {}, | 974 | metadata: {}, |
| 975 | payload: { | 975 | payload: { |
| 976 | threadId, | 976 | threadId, |
| 977 | projectId: ProjectId.makeUnsafe("project-delete-files"), | 977 | projectId: ProjectId.make("project-delete-files"), |
| 978 | title: "Thread Delete Files", | 978 | title: "Thread Delete Files", |
| 979 | modelSelection: { | 979 | modelSelection: { |
| 980 | provider: "codex", | 980 | provider: "codex", |
| ... | @@ -990,17 +990,17 @@ it.layer(Layer.fresh(makeProjectionPipelinePrefixedTestLayer("t3-projection-atta | ... | @@ -990,17 +990,17 @@ it.layer(Layer.fresh(makeProjectionPipelinePrefixedTestLayer("t3-projection-atta |
| 990 | 990 | ||
| 991 | yield* appendAndProject({ | 991 | yield* appendAndProject({ |
| 992 | type: "thread.message-sent", | 992 | type: "thread.message-sent", |
| 993 | eventId: EventId.makeUnsafe("evt-delete-files-3"), | 993 | eventId: EventId.make("evt-delete-files-3"), |
| 994 | aggregateKind: "thread", | 994 | aggregateKind: "thread", |
| 995 | aggregateId: threadId, | 995 | aggregateId: threadId, |
| 996 | occurredAt: now, | 996 | occurredAt: now, |
| 997 | commandId: CommandId.makeUnsafe("cmd-delete-files-3"), | 997 | commandId: CommandId.make("cmd-delete-files-3"), |
| 998 | causationEventId: null, | 998 | causationEventId: null, |
| 999 | correlationId: CorrelationId.makeUnsafe("cmd-delete-files-3"), | 999 | correlationId: CorrelationId.make("cmd-delete-files-3"), |
| 1000 | metadata: {}, | 1000 | metadata: {}, |
| 1001 | payload: { | 1001 | payload: { |
| 1002 | threadId, | 1002 | threadId, |
| 1003 | messageId: MessageId.makeUnsafe("message-delete-files"), | 1003 | messageId: MessageId.make("message-delete-files"), |
| 1004 | role: "user", | 1004 | role: "user", |
| 1005 | text: "Delete", | 1005 | text: "Delete", |
| 1006 | attachments: [ | 1006 | attachments: [ |
| ... | @@ -1032,13 +1032,13 @@ it.layer(Layer.fresh(makeProjectionPipelinePrefixedTestLayer("t3-projection-atta | ... | @@ -1032,13 +1032,13 @@ it.layer(Layer.fresh(makeProjectionPipelinePrefixedTestLayer("t3-projection-atta |
| 1032 | 1032 | ||
| 1033 | yield* appendAndProject({ | 1033 | yield* appendAndProject({ |
| 1034 | type: "thread.deleted", | 1034 | type: "thread.deleted", |
| 1035 | eventId: EventId.makeUnsafe("evt-delete-files-4"), | 1035 | eventId: EventId.make("evt-delete-files-4"), |
| 1036 | aggregateKind: "thread", | 1036 | aggregateKind: "thread", |
| 1037 | aggregateId: threadId, | 1037 | aggregateId: threadId, |
| 1038 | occurredAt: now, | 1038 | occurredAt: now, |
| 1039 | commandId: CommandId.makeUnsafe("cmd-delete-files-4"), | 1039 | commandId: CommandId.make("cmd-delete-files-4"), |
| 1040 | causationEventId: null, | 1040 | causationEventId: null, |
| 1041 | correlationId: CorrelationId.makeUnsafe("cmd-delete-files-4"), | 1041 | correlationId: CorrelationId.make("cmd-delete-files-4"), |
| 1042 | metadata: {}, | 1042 | metadata: {}, |
| 1043 | payload: { | 1043 | payload: { |
| 1044 | threadId, | 1044 | threadId, |
| ... | @@ -1072,16 +1072,16 @@ it.layer(Layer.fresh(makeProjectionPipelinePrefixedTestLayer("t3-projection-atta | ... | @@ -1072,16 +1072,16 @@ it.layer(Layer.fresh(makeProjectionPipelinePrefixedTestLayer("t3-projection-atta |
| 1072 | 1072 | ||
| 1073 | yield* eventStore.append({ | 1073 | yield* eventStore.append({ |
| 1074 | type: "thread.deleted", | 1074 | type: "thread.deleted", |
| 1075 | eventId: EventId.makeUnsafe("evt-unsafe-thread-delete"), | 1075 | eventId: EventId.make("evt-unsafe-thread-delete"), |
| 1076 | aggregateKind: "thread", | 1076 | aggregateKind: "thread", |
| 1077 | aggregateId: ThreadId.makeUnsafe(".."), | 1077 | aggregateId: ThreadId.make(".."), |
| 1078 | occurredAt: now, | 1078 | occurredAt: now, |
| 1079 | commandId: CommandId.makeUnsafe("cmd-unsafe-thread-delete"), | 1079 | commandId: CommandId.make("cmd-unsafe-thread-delete"), |
| 1080 | causationEventId: null, | 1080 | causationEventId: null, |
| 1081 | correlationId: CorrelationId.makeUnsafe("cmd-unsafe-thread-delete"), | 1081 | correlationId: CorrelationId.make("cmd-unsafe-thread-delete"), |
| 1082 | metadata: {}, | 1082 | metadata: {}, |
| 1083 | payload: { | 1083 | payload: { |
| 1084 | threadId: ThreadId.makeUnsafe(".."), | 1084 | threadId: ThreadId.make(".."), |
| 1085 | deletedAt: now, | 1085 | deletedAt: now, |
| 1086 | }, | 1086 | }, |
| 1087 | }); | 1087 | }); |
| ... | @@ -1106,16 +1106,16 @@ it.layer(BaseTestLayer)("OrchestrationProjectionPipeline", (it) => { | ... | @@ -1106,16 +1106,16 @@ it.layer(BaseTestLayer)("OrchestrationProjectionPipeline", (it) => { |
| 1106 | 1106 | ||
| 1107 | yield* eventStore.append({ | 1107 | yield* eventStore.append({ |
| 1108 | type: "project.created", | 1108 | type: "project.created", |
| 1109 | eventId: EventId.makeUnsafe("evt-a1"), | 1109 | eventId: EventId.make("evt-a1"), |
| 1110 | aggregateKind: "project", | 1110 | aggregateKind: "project", |
| 1111 | aggregateId: ProjectId.makeUnsafe("project-a"), | 1111 | aggregateId: ProjectId.make("project-a"), |
| 1112 | occurredAt: now, | 1112 | occurredAt: now, |
| 1113 | commandId: CommandId.makeUnsafe("cmd-a1"), | 1113 | commandId: CommandId.make("cmd-a1"), |
| 1114 | causationEventId: null, | 1114 | causationEventId: null, |
| 1115 | correlationId: CorrelationId.makeUnsafe("cmd-a1"), | 1115 | correlationId: CorrelationId.make("cmd-a1"), |
| 1116 | metadata: {}, | 1116 | metadata: {}, |
| 1117 | payload: { | 1117 | payload: { |
| 1118 | projectId: ProjectId.makeUnsafe("project-a"), | 1118 | projectId: ProjectId.make("project-a"), |
| 1119 | title: "Project A", | 1119 | title: "Project A", |
| 1120 | workspaceRoot: "/tmp/project-a", | 1120 | workspaceRoot: "/tmp/project-a", |
| 1121 | defaultModelSelection: null, | 1121 | defaultModelSelection: null, |
| ... | @@ -1127,17 +1127,17 @@ it.layer(BaseTestLayer)("OrchestrationProjectionPipeline", (it) => { | ... | @@ -1127,17 +1127,17 @@ it.layer(BaseTestLayer)("OrchestrationProjectionPipeline", (it) => { |
| 1127 | 1127 | ||
| 1128 | yield* eventStore.append({ | 1128 | yield* eventStore.append({ |
| 1129 | type: "thread.created", | 1129 | type: "thread.created", |
| 1130 | eventId: EventId.makeUnsafe("evt-a2"), | 1130 | eventId: EventId.make("evt-a2"), |
| 1131 | aggregateKind: "thread", | 1131 | aggregateKind: "thread", |
| 1132 | aggregateId: ThreadId.makeUnsafe("thread-a"), | 1132 | aggregateId: ThreadId.make("thread-a"), |
| 1133 | occurredAt: now, | 1133 | occurredAt: now, |
| 1134 | commandId: CommandId.makeUnsafe("cmd-a2"), | 1134 | commandId: CommandId.make("cmd-a2"), |
| 1135 | causationEventId: null, | 1135 | causationEventId: null, |
| 1136 | correlationId: CorrelationId.makeUnsafe("cmd-a2"), | 1136 | correlationId: CorrelationId.make("cmd-a2"), |
| 1137 | metadata: {}, | 1137 | metadata: {}, |
| 1138 | payload: { | 1138 | payload: { |
| 1139 | threadId: ThreadId.makeUnsafe("thread-a"), | 1139 | threadId: ThreadId.make("thread-a"), |
| 1140 | projectId: ProjectId.makeUnsafe("project-a"), | 1140 | projectId: ProjectId.make("project-a"), |
| 1141 | title: "Thread A", | 1141 | title: "Thread A", |
| 1142 | modelSelection: { | 1142 | modelSelection: { |
| 1143 | provider: "codex", | 1143 | provider: "codex", |
| ... | @@ -1153,17 +1153,17 @@ it.layer(BaseTestLayer)("OrchestrationProjectionPipeline", (it) => { | ... | @@ -1153,17 +1153,17 @@ it.layer(BaseTestLayer)("OrchestrationProjectionPipeline", (it) => { |
| 1153 | 1153 | ||
| 1154 | yield* eventStore.append({ | 1154 | yield* eventStore.append({ |
| 1155 | type: "thread.message-sent", | 1155 | type: "thread.message-sent", |
| 1156 | eventId: EventId.makeUnsafe("evt-a3"), | 1156 | eventId: EventId.make("evt-a3"), |
| 1157 | aggregateKind: "thread", | 1157 | aggregateKind: "thread", |
| 1158 | aggregateId: ThreadId.makeUnsafe("thread-a"), | 1158 | aggregateId: ThreadId.make("thread-a"), |
| 1159 | occurredAt: now, | 1159 | occurredAt: now, |
| 1160 | commandId: CommandId.makeUnsafe("cmd-a3"), | 1160 | commandId: CommandId.make("cmd-a3"), |
| 1161 | causationEventId: null, | 1161 | causationEventId: null, |
| 1162 | correlationId: CorrelationId.makeUnsafe("cmd-a3"), | 1162 | correlationId: CorrelationId.make("cmd-a3"), |
| 1163 | metadata: {}, | 1163 | metadata: {}, |
| 1164 | payload: { | 1164 | payload: { |
| 1165 | threadId: ThreadId.makeUnsafe("thread-a"), | 1165 | threadId: ThreadId.make("thread-a"), |
| 1166 | messageId: MessageId.makeUnsafe("message-a"), | 1166 | messageId: MessageId.make("message-a"), |
| 1167 | role: "assistant", | 1167 | role: "assistant", |
| 1168 | text: "hello", | 1168 | text: "hello", |
| 1169 | turnId: null, | 1169 | turnId: null, |
| ... | @@ -1177,17 +1177,17 @@ it.layer(BaseTestLayer)("OrchestrationProjectionPipeline", (it) => { | ... | @@ -1177,17 +1177,17 @@ it.layer(BaseTestLayer)("OrchestrationProjectionPipeline", (it) => { |
| 1177 | 1177 | ||
| 1178 | yield* eventStore.append({ | 1178 | yield* eventStore.append({ |
| 1179 | type: "thread.message-sent", | 1179 | type: "thread.message-sent", |
| 1180 | eventId: EventId.makeUnsafe("evt-a4"), | 1180 | eventId: EventId.make("evt-a4"), |
| 1181 | aggregateKind: "thread", | 1181 | aggregateKind: "thread", |
| 1182 | aggregateId: ThreadId.makeUnsafe("thread-a"), | 1182 | aggregateId: ThreadId.make("thread-a"), |
| 1183 | occurredAt: now, | 1183 | occurredAt: now, |
| 1184 | commandId: CommandId.makeUnsafe("cmd-a4"), | 1184 | commandId: CommandId.make("cmd-a4"), |
| 1185 | causationEventId: null, | 1185 | causationEventId: null, |
| 1186 | correlationId: CorrelationId.makeUnsafe("cmd-a4"), | 1186 | correlationId: CorrelationId.make("cmd-a4"), |
| 1187 | metadata: {}, | 1187 | metadata: {}, |
| 1188 | payload: { | 1188 | payload: { |
| 1189 | threadId: ThreadId.makeUnsafe("thread-a"), | 1189 | threadId: ThreadId.make("thread-a"), |
| 1190 | messageId: MessageId.makeUnsafe("message-a"), | 1190 | messageId: MessageId.make("message-a"), |
| 1191 | role: "assistant", | 1191 | role: "assistant", |
| 1192 | text: " world", | 1192 | text: " world", |
| 1193 | turnId: null, | 1193 | turnId: null, |
| ... | @@ -1233,16 +1233,16 @@ it.layer(BaseTestLayer)("OrchestrationProjectionPipeline", (it) => { | ... | @@ -1233,16 +1233,16 @@ it.layer(BaseTestLayer)("OrchestrationProjectionPipeline", (it) => { |
| 1233 | 1233 | ||
| 1234 | yield* eventStore.append({ | 1234 | yield* eventStore.append({ |
| 1235 | type: "project.created", | 1235 | type: "project.created", |
| 1236 | eventId: EventId.makeUnsafe("evt-empty-1"), | 1236 | eventId: EventId.make("evt-empty-1"), |
| 1237 | aggregateKind: "project", | 1237 | aggregateKind: "project", |
| 1238 | aggregateId: ProjectId.makeUnsafe("project-empty"), | 1238 | aggregateId: ProjectId.make("project-empty"), |
| 1239 | occurredAt: now, | 1239 | occurredAt: now, |
| 1240 | commandId: CommandId.makeUnsafe("cmd-empty-1"), | 1240 | commandId: CommandId.make("cmd-empty-1"), |
| 1241 | causationEventId: null, | 1241 | causationEventId: null, |
| 1242 | correlationId: CorrelationId.makeUnsafe("cmd-empty-1"), | 1242 | correlationId: CorrelationId.make("cmd-empty-1"), |
| 1243 | metadata: {}, | 1243 | metadata: {}, |
| 1244 | payload: { | 1244 | payload: { |
| 1245 | projectId: ProjectId.makeUnsafe("project-empty"), | 1245 | projectId: ProjectId.make("project-empty"), |
| 1246 | title: "Project Empty", | 1246 | title: "Project Empty", |
| 1247 | workspaceRoot: "/tmp/project-empty", | 1247 | workspaceRoot: "/tmp/project-empty", |
| 1248 | defaultModelSelection: null, | 1248 | defaultModelSelection: null, |
| ... | @@ -1254,17 +1254,17 @@ it.layer(BaseTestLayer)("OrchestrationProjectionPipeline", (it) => { | ... | @@ -1254,17 +1254,17 @@ it.layer(BaseTestLayer)("OrchestrationProjectionPipeline", (it) => { |
| 1254 | 1254 | ||
| 1255 | yield* eventStore.append({ | 1255 | yield* eventStore.append({ |
| 1256 | type: "thread.created", | 1256 | type: "thread.created", |
| 1257 | eventId: EventId.makeUnsafe("evt-empty-2"), | 1257 | eventId: EventId.make("evt-empty-2"), |
| 1258 | aggregateKind: "thread", | 1258 | aggregateKind: "thread", |
| 1259 | aggregateId: ThreadId.makeUnsafe("thread-empty"), | 1259 | aggregateId: ThreadId.make("thread-empty"), |
| 1260 | occurredAt: now, | 1260 | occurredAt: now, |
| 1261 | commandId: CommandId.makeUnsafe("cmd-empty-2"), | 1261 | commandId: CommandId.make("cmd-empty-2"), |
| 1262 | causationEventId: null, | 1262 | causationEventId: null, |
| 1263 | correlationId: CorrelationId.makeUnsafe("cmd-empty-2"), | 1263 | correlationId: CorrelationId.make("cmd-empty-2"), |
| 1264 | metadata: {}, | 1264 | metadata: {}, |
| 1265 | payload: { | 1265 | payload: { |
| 1266 | threadId: ThreadId.makeUnsafe("thread-empty"), | 1266 | threadId: ThreadId.make("thread-empty"), |
| 1267 | projectId: ProjectId.makeUnsafe("project-empty"), | 1267 | projectId: ProjectId.make("project-empty"), |
| 1268 | title: "Thread Empty", | 1268 | title: "Thread Empty", |
| 1269 | modelSelection: { | 1269 | modelSelection: { |
| 1270 | provider: "codex", | 1270 | provider: "codex", |
| ... | @@ -1280,17 +1280,17 @@ it.layer(BaseTestLayer)("OrchestrationProjectionPipeline", (it) => { | ... | @@ -1280,17 +1280,17 @@ it.layer(BaseTestLayer)("OrchestrationProjectionPipeline", (it) => { |
| 1280 | 1280 | ||
| 1281 | yield* eventStore.append({ | 1281 | yield* eventStore.append({ |
| 1282 | type: "thread.message-sent", | 1282 | type: "thread.message-sent", |
| 1283 | eventId: EventId.makeUnsafe("evt-empty-3"), | 1283 | eventId: EventId.make("evt-empty-3"), |
| 1284 | aggregateKind: "thread", | 1284 | aggregateKind: "thread", |
| 1285 | aggregateId: ThreadId.makeUnsafe("thread-empty"), | 1285 | aggregateId: ThreadId.make("thread-empty"), |
| 1286 | occurredAt: now, | 1286 | occurredAt: now, |
| 1287 | commandId: CommandId.makeUnsafe("cmd-empty-3"), | 1287 | commandId: CommandId.make("cmd-empty-3"), |
| 1288 | causationEventId: null, | 1288 | causationEventId: null, |
| 1289 | correlationId: CorrelationId.makeUnsafe("cmd-empty-3"), | 1289 | correlationId: CorrelationId.make("cmd-empty-3"), |
| 1290 | metadata: {}, | 1290 | metadata: {}, |
| 1291 | payload: { | 1291 | payload: { |
| 1292 | threadId: ThreadId.makeUnsafe("thread-empty"), | 1292 | threadId: ThreadId.make("thread-empty"), |
| 1293 | messageId: MessageId.makeUnsafe("assistant-empty"), | 1293 | messageId: MessageId.make("assistant-empty"), |
| 1294 | role: "assistant", | 1294 | role: "assistant", |
| 1295 | text: "Hello", | 1295 | text: "Hello", |
| 1296 | turnId: null, | 1296 | turnId: null, |
| ... | @@ -1302,17 +1302,17 @@ it.layer(BaseTestLayer)("OrchestrationProjectionPipeline", (it) => { | ... | @@ -1302,17 +1302,17 @@ it.layer(BaseTestLayer)("OrchestrationProjectionPipeline", (it) => { |
| 1302 | 1302 | ||
| 1303 | yield* eventStore.append({ | 1303 | yield* eventStore.append({ |
| 1304 | type: "thread.message-sent", | 1304 | type: "thread.message-sent", |
| 1305 | eventId: EventId.makeUnsafe("evt-empty-4"), | 1305 | eventId: EventId.make("evt-empty-4"), |
| 1306 | aggregateKind: "thread", | 1306 | aggregateKind: "thread", |
| 1307 | aggregateId: ThreadId.makeUnsafe("thread-empty"), | 1307 | aggregateId: ThreadId.make("thread-empty"), |
| 1308 | occurredAt: now, | 1308 | occurredAt: now, |
| 1309 | commandId: CommandId.makeUnsafe("cmd-empty-4"), | 1309 | commandId: CommandId.make("cmd-empty-4"), |
| 1310 | causationEventId: null, | 1310 | causationEventId: null, |
| 1311 | correlationId: CorrelationId.makeUnsafe("cmd-empty-4"), | 1311 | correlationId: CorrelationId.make("cmd-empty-4"), |
| 1312 | metadata: {}, | 1312 | metadata: {}, |
| 1313 | payload: { | 1313 | payload: { |
| 1314 | threadId: ThreadId.makeUnsafe("thread-empty"), | 1314 | threadId: ThreadId.make("thread-empty"), |
| 1315 | messageId: MessageId.makeUnsafe("assistant-empty"), | 1315 | messageId: MessageId.make("assistant-empty"), |
| 1316 | role: "assistant", | 1316 | role: "assistant", |
| 1317 | text: " world", | 1317 | text: " world", |
| 1318 | turnId: null, | 1318 | turnId: null, |
| ... | @@ -1324,17 +1324,17 @@ it.layer(BaseTestLayer)("OrchestrationProjectionPipeline", (it) => { | ... | @@ -1324,17 +1324,17 @@ it.layer(BaseTestLayer)("OrchestrationProjectionPipeline", (it) => { |
| 1324 | 1324 | ||
| 1325 | yield* eventStore.append({ | 1325 | yield* eventStore.append({ |
| 1326 | type: "thread.message-sent", | 1326 | type: "thread.message-sent", |
| 1327 | eventId: EventId.makeUnsafe("evt-empty-5"), | 1327 | eventId: EventId.make("evt-empty-5"), |
| 1328 | aggregateKind: "thread", | 1328 | aggregateKind: "thread", |
| 1329 | aggregateId: ThreadId.makeUnsafe("thread-empty"), | 1329 | aggregateId: ThreadId.make("thread-empty"), |
| 1330 | occurredAt: now, | 1330 | occurredAt: now, |
| 1331 | commandId: CommandId.makeUnsafe("cmd-empty-5"), | 1331 | commandId: CommandId.make("cmd-empty-5"), |
| 1332 | causationEventId: null, | 1332 | causationEventId: null, |
| 1333 | correlationId: CorrelationId.makeUnsafe("cmd-empty-5"), | 1333 | correlationId: CorrelationId.make("cmd-empty-5"), |
| 1334 | metadata: {}, | 1334 | metadata: {}, |
| 1335 | payload: { | 1335 | payload: { |
| 1336 | threadId: ThreadId.makeUnsafe("thread-empty"), | 1336 | threadId: ThreadId.make("thread-empty"), |
| 1337 | messageId: MessageId.makeUnsafe("assistant-empty"), | 1337 | messageId: MessageId.make("assistant-empty"), |
| 1338 | role: "assistant", | 1338 | role: "assistant", |
| 1339 | text: "", | 1339 | text: "", |
| 1340 | turnId: null, | 1340 | turnId: null, |
| ... | @@ -1373,16 +1373,16 @@ it.layer(BaseTestLayer)("OrchestrationProjectionPipeline", (it) => { | ... | @@ -1373,16 +1373,16 @@ it.layer(BaseTestLayer)("OrchestrationProjectionPipeline", (it) => { |
| 1373 | 1373 | ||
| 1374 | yield* appendAndProject({ | 1374 | yield* appendAndProject({ |
| 1375 | type: "project.created", | 1375 | type: "project.created", |
| 1376 | eventId: EventId.makeUnsafe("evt-conflict-1"), | 1376 | eventId: EventId.make("evt-conflict-1"), |
| 1377 | aggregateKind: "project", | 1377 | aggregateKind: "project", |
| 1378 | aggregateId: ProjectId.makeUnsafe("project-conflict"), | 1378 | aggregateId: ProjectId.make("project-conflict"), |
| 1379 | occurredAt: "2026-02-26T13:00:00.000Z", | 1379 | occurredAt: "2026-02-26T13:00:00.000Z", |
| 1380 | commandId: CommandId.makeUnsafe("cmd-conflict-1"), | 1380 | commandId: CommandId.make("cmd-conflict-1"), |
| 1381 | causationEventId: null, | 1381 | causationEventId: null, |
| 1382 | correlationId: CorrelationId.makeUnsafe("cmd-conflict-1"), | 1382 | correlationId: CorrelationId.make("cmd-conflict-1"), |
| 1383 | metadata: {}, | 1383 | metadata: {}, |
| 1384 | payload: { | 1384 | payload: { |
| 1385 | projectId: ProjectId.makeUnsafe("project-conflict"), | 1385 | projectId: ProjectId.make("project-conflict"), |
| 1386 | title: "Project Conflict", | 1386 | title: "Project Conflict", |
| 1387 | workspaceRoot: "/tmp/project-conflict", | 1387 | workspaceRoot: "/tmp/project-conflict", |
| 1388 | defaultModelSelection: null, | 1388 | defaultModelSelection: null, |
| ... | @@ -1394,17 +1394,17 @@ it.layer(BaseTestLayer)("OrchestrationProjectionPipeline", (it) => { | ... | @@ -1394,17 +1394,17 @@ it.layer(BaseTestLayer)("OrchestrationProjectionPipeline", (it) => { |
| 1394 | 1394 | ||
| 1395 | yield* appendAndProject({ | 1395 | yield* appendAndProject({ |
| 1396 | type: "thread.created", | 1396 | type: "thread.created", |
| 1397 | eventId: EventId.makeUnsafe("evt-conflict-2"), | 1397 | eventId: EventId.make("evt-conflict-2"), |
| 1398 | aggregateKind: "thread", | 1398 | aggregateKind: "thread", |
| 1399 | aggregateId: ThreadId.makeUnsafe("thread-conflict"), | 1399 | aggregateId: ThreadId.make("thread-conflict"), |
| 1400 | occurredAt: "2026-02-26T13:00:01.000Z", | 1400 | occurredAt: "2026-02-26T13:00:01.000Z", |
| 1401 | commandId: CommandId.makeUnsafe("cmd-conflict-2"), | 1401 | commandId: CommandId.make("cmd-conflict-2"), |
| 1402 | causationEventId: null, | 1402 | causationEventId: null, |
| 1403 | correlationId: CorrelationId.makeUnsafe("cmd-conflict-2"), | 1403 | correlationId: CorrelationId.make("cmd-conflict-2"), |
| 1404 | metadata: {}, | 1404 | metadata: {}, |
| 1405 | payload: { | 1405 | payload: { |
| 1406 | threadId: ThreadId.makeUnsafe("thread-conflict"), | 1406 | threadId: ThreadId.make("thread-conflict"), |
| 1407 | projectId: ProjectId.makeUnsafe("project-conflict"), | 1407 | projectId: ProjectId.make("project-conflict"), |
| 1408 | title: "Thread Conflict", | 1408 | title: "Thread Conflict", |
| 1409 | modelSelection: { | 1409 | modelSelection: { |
| 1410 | provider: "codex", | 1410 | provider: "codex", |
| ... | @@ -1420,37 +1420,37 @@ it.layer(BaseTestLayer)("OrchestrationProjectionPipeline", (it) => { | ... | @@ -1420,37 +1420,37 @@ it.layer(BaseTestLayer)("OrchestrationProjectionPipeline", (it) => { |
| 1420 | 1420 | ||
| 1421 | yield* appendAndProject({ | 1421 | yield* appendAndProject({ |
| 1422 | type: "thread.turn-interrupt-requested", | 1422 | type: "thread.turn-interrupt-requested", |
| 1423 | eventId: EventId.makeUnsafe("evt-conflict-3"), | 1423 | eventId: EventId.make("evt-conflict-3"), |
| 1424 | aggregateKind: "thread", | 1424 | aggregateKind: "thread", |
| 1425 | aggregateId: ThreadId.makeUnsafe("thread-conflict"), | 1425 | aggregateId: ThreadId.make("thread-conflict"), |
| 1426 | occurredAt: "2026-02-26T13:00:02.000Z", | 1426 | occurredAt: "2026-02-26T13:00:02.000Z", |
| 1427 | commandId: CommandId.makeUnsafe("cmd-conflict-3"), | 1427 | commandId: CommandId.make("cmd-conflict-3"), |
| 1428 | causationEventId: null, | 1428 | causationEventId: null, |
| 1429 | correlationId: CorrelationId.makeUnsafe("cmd-conflict-3"), | 1429 | correlationId: CorrelationId.make("cmd-conflict-3"), |
| 1430 | metadata: {}, | 1430 | metadata: {}, |
| 1431 | payload: { | 1431 | payload: { |
| 1432 | threadId: ThreadId.makeUnsafe("thread-conflict"), | 1432 | threadId: ThreadId.make("thread-conflict"), |
| 1433 | turnId: TurnId.makeUnsafe("turn-interrupted"), | 1433 | turnId: TurnId.make("turn-interrupted"), |
| 1434 | createdAt: "2026-02-26T13:00:02.000Z", | 1434 | createdAt: "2026-02-26T13:00:02.000Z", |
| 1435 | }, | 1435 | }, |
| 1436 | }); | 1436 | }); |
| 1437 | 1437 | ||
| 1438 | yield* appendAndProject({ | 1438 | yield* appendAndProject({ |
| 1439 | type: "thread.message-sent", | 1439 | type: "thread.message-sent", |
| 1440 | eventId: EventId.makeUnsafe("evt-conflict-4"), | 1440 | eventId: EventId.make("evt-conflict-4"), |
| 1441 | aggregateKind: "thread", | 1441 | aggregateKind: "thread", |
| 1442 | aggregateId: ThreadId.makeUnsafe("thread-conflict"), | 1442 | aggregateId: ThreadId.make("thread-conflict"), |
| 1443 | occurredAt: "2026-02-26T13:00:03.000Z", | 1443 | occurredAt: "2026-02-26T13:00:03.000Z", |
| 1444 | commandId: CommandId.makeUnsafe("cmd-conflict-4"), | 1444 | commandId: CommandId.make("cmd-conflict-4"), |
| 1445 | causationEventId: null, | 1445 | causationEventId: null, |
| 1446 | correlationId: CorrelationId.makeUnsafe("cmd-conflict-4"), | 1446 | correlationId: CorrelationId.make("cmd-conflict-4"), |
| 1447 | metadata: {}, | 1447 | metadata: {}, |
| 1448 | payload: { | 1448 | payload: { |
| 1449 | threadId: ThreadId.makeUnsafe("thread-conflict"), | 1449 | threadId: ThreadId.make("thread-conflict"), |
| 1450 | messageId: MessageId.makeUnsafe("assistant-conflict"), | 1450 | messageId: MessageId.make("assistant-conflict"), |
| 1451 | role: "assistant", | 1451 | role: "assistant", |
| 1452 | text: "done", | 1452 | text: "done", |
| 1453 | turnId: TurnId.makeUnsafe("turn-completed"), | 1453 | turnId: TurnId.make("turn-completed"), |
| 1454 | streaming: false, | 1454 | streaming: false, |
| 1455 | createdAt: "2026-02-26T13:00:03.000Z", | 1455 | createdAt: "2026-02-26T13:00:03.000Z", |
| 1456 | updatedAt: "2026-02-26T13:00:03.000Z", | 1456 | updatedAt: "2026-02-26T13:00:03.000Z", |
| ... | @@ -1459,22 +1459,22 @@ it.layer(BaseTestLayer)("OrchestrationProjectionPipeline", (it) => { | ... | @@ -1459,22 +1459,22 @@ it.layer(BaseTestLayer)("OrchestrationProjectionPipeline", (it) => { |
| 1459 | 1459 | ||
| 1460 | yield* appendAndProject({ | 1460 | yield* appendAndProject({ |
| 1461 | type: "thread.turn-diff-completed", | 1461 | type: "thread.turn-diff-completed", |
| 1462 | eventId: EventId.makeUnsafe("evt-conflict-5"), | 1462 | eventId: EventId.make("evt-conflict-5"), |
| 1463 | aggregateKind: "thread", | 1463 | aggregateKind: "thread", |
| 1464 | aggregateId: ThreadId.makeUnsafe("thread-conflict"), | 1464 | aggregateId: ThreadId.make("thread-conflict"), |
| 1465 | occurredAt: "2026-02-26T13:00:04.000Z", | 1465 | occurredAt: "2026-02-26T13:00:04.000Z", |
| 1466 | commandId: CommandId.makeUnsafe("cmd-conflict-5"), | 1466 | commandId: CommandId.make("cmd-conflict-5"), |
| 1467 | causationEventId: null, | 1467 | causationEventId: null, |
| 1468 | correlationId: CorrelationId.makeUnsafe("cmd-conflict-5"), | 1468 | correlationId: CorrelationId.make("cmd-conflict-5"), |
| 1469 | metadata: {}, | 1469 | metadata: {}, |
| 1470 | payload: { | 1470 | payload: { |
| 1471 | threadId: ThreadId.makeUnsafe("thread-conflict"), | 1471 | threadId: ThreadId.make("thread-conflict"), |
| 1472 | turnId: TurnId.makeUnsafe("turn-completed"), | 1472 | turnId: TurnId.make("turn-completed"), |
| 1473 | checkpointTurnCount: 1, | 1473 | checkpointTurnCount: 1, |
| 1474 | checkpointRef: CheckpointRef.makeUnsafe("refs/t3/checkpoints/thread-conflict/turn/1"), | 1474 | checkpointRef: CheckpointRef.make("refs/t3/checkpoints/thread-conflict/turn/1"), |
| 1475 | status: "ready", | 1475 | status: "ready", |
| 1476 | files: [], | 1476 | files: [], |
| 1477 | assistantMessageId: MessageId.makeUnsafe("assistant-conflict"), | 1477 | assistantMessageId: MessageId.make("assistant-conflict"), |
| 1478 | completedAt: "2026-02-26T13:00:04.000Z", | 1478 | completedAt: "2026-02-26T13:00:04.000Z", |
| 1479 | }, | 1479 | }, |
| 1480 | }); | 1480 | }); |
| ... | @@ -1517,16 +1517,16 @@ it.layer(BaseTestLayer)("OrchestrationProjectionPipeline", (it) => { | ... | @@ -1517,16 +1517,16 @@ it.layer(BaseTestLayer)("OrchestrationProjectionPipeline", (it) => { |
| 1517 | 1517 | ||
| 1518 | yield* appendAndProject({ | 1518 | yield* appendAndProject({ |
| 1519 | type: "project.created", | 1519 | type: "project.created", |
| 1520 | eventId: EventId.makeUnsafe("evt-revert-1"), | 1520 | eventId: EventId.make("evt-revert-1"), |
| 1521 | aggregateKind: "project", | 1521 | aggregateKind: "project", |
| 1522 | aggregateId: ProjectId.makeUnsafe("project-revert"), | 1522 | aggregateId: ProjectId.make("project-revert"), |
| 1523 | occurredAt: "2026-02-26T12:00:00.000Z", | 1523 | occurredAt: "2026-02-26T12:00:00.000Z", |
| 1524 | commandId: CommandId.makeUnsafe("cmd-revert-1"), | 1524 | commandId: CommandId.make("cmd-revert-1"), |
| 1525 | causationEventId: null, | 1525 | causationEventId: null, |
| 1526 | correlationId: CorrelationId.makeUnsafe("cmd-revert-1"), | 1526 | correlationId: CorrelationId.make("cmd-revert-1"), |
| 1527 | metadata: {}, | 1527 | metadata: {}, |
| 1528 | payload: { | 1528 | payload: { |
| 1529 | projectId: ProjectId.makeUnsafe("project-revert"), | 1529 | projectId: ProjectId.make("project-revert"), |
| 1530 | title: "Project Revert", | 1530 | title: "Project Revert", |
| 1531 | workspaceRoot: "/tmp/project-revert", | 1531 | workspaceRoot: "/tmp/project-revert", |
| 1532 | defaultModelSelection: null, | 1532 | defaultModelSelection: null, |
| ... | @@ -1538,17 +1538,17 @@ it.layer(BaseTestLayer)("OrchestrationProjectionPipeline", (it) => { | ... | @@ -1538,17 +1538,17 @@ it.layer(BaseTestLayer)("OrchestrationProjectionPipeline", (it) => { |
| 1538 | 1538 | ||
| 1539 | yield* appendAndProject({ | 1539 | yield* appendAndProject({ |
| 1540 | type: "thread.created", | 1540 | type: "thread.created", |
| 1541 | eventId: EventId.makeUnsafe("evt-revert-2"), | 1541 | eventId: EventId.make("evt-revert-2"), |
| 1542 | aggregateKind: "thread", | 1542 | aggregateKind: "thread", |
| 1543 | aggregateId: ThreadId.makeUnsafe("thread-revert"), | 1543 | aggregateId: ThreadId.make("thread-revert"), |
| 1544 | occurredAt: "2026-02-26T12:00:01.000Z", | 1544 | occurredAt: "2026-02-26T12:00:01.000Z", |
| 1545 | commandId: CommandId.makeUnsafe("cmd-revert-2"), | 1545 | commandId: CommandId.make("cmd-revert-2"), |
| 1546 | causationEventId: null, | 1546 | causationEventId: null, |
| 1547 | correlationId: CorrelationId.makeUnsafe("cmd-revert-2"), | 1547 | correlationId: CorrelationId.make("cmd-revert-2"), |
| 1548 | metadata: {}, | 1548 | metadata: {}, |
| 1549 | payload: { | 1549 | payload: { |
| 1550 | threadId: ThreadId.makeUnsafe("thread-revert"), | 1550 | threadId: ThreadId.make("thread-revert"), |
| 1551 | projectId: ProjectId.makeUnsafe("project-revert"), | 1551 | projectId: ProjectId.make("project-revert"), |
| 1552 | title: "Thread Revert", | 1552 | title: "Thread Revert", |
| 1553 | modelSelection: { | 1553 | modelSelection: { |
| 1554 | provider: "codex", | 1554 | provider: "codex", |
| ... | @@ -1564,42 +1564,42 @@ it.layer(BaseTestLayer)("OrchestrationProjectionPipeline", (it) => { | ... | @@ -1564,42 +1564,42 @@ it.layer(BaseTestLayer)("OrchestrationProjectionPipeline", (it) => { |
| 1564 | 1564 | ||
| 1565 | yield* appendAndProject({ | 1565 | yield* appendAndProject({ |
| 1566 | type: "thread.turn-diff-completed", | 1566 | type: "thread.turn-diff-completed", |
| 1567 | eventId: EventId.makeUnsafe("evt-revert-3"), | 1567 | eventId: EventId.make("evt-revert-3"), |
| 1568 | aggregateKind: "thread", | 1568 | aggregateKind: "thread", |
| 1569 | aggregateId: ThreadId.makeUnsafe("thread-revert"), | 1569 | aggregateId: ThreadId.make("thread-revert"), |
| 1570 | occurredAt: "2026-02-26T12:00:02.000Z", | 1570 | occurredAt: "2026-02-26T12:00:02.000Z", |
| 1571 | commandId: CommandId.makeUnsafe("cmd-revert-3"), | 1571 | commandId: CommandId.make("cmd-revert-3"), |
| 1572 | causationEventId: null, | 1572 | causationEventId: null, |
| 1573 | correlationId: CorrelationId.makeUnsafe("cmd-revert-3"), | 1573 | correlationId: CorrelationId.make("cmd-revert-3"), |
| 1574 | metadata: {}, | 1574 | metadata: {}, |
| 1575 | payload: { | 1575 | payload: { |
| 1576 | threadId: ThreadId.makeUnsafe("thread-revert"), | 1576 | threadId: ThreadId.make("thread-revert"), |
| 1577 | turnId: TurnId.makeUnsafe("turn-1"), | 1577 | turnId: TurnId.make("turn-1"), |
| 1578 | checkpointTurnCount: 1, | 1578 | checkpointTurnCount: 1, |
| 1579 | checkpointRef: CheckpointRef.makeUnsafe("refs/t3/checkpoints/thread-revert/turn/1"), | 1579 | checkpointRef: CheckpointRef.make("refs/t3/checkpoints/thread-revert/turn/1"), |
| 1580 | status: "ready", | 1580 | status: "ready", |
| 1581 | files: [], | 1581 | files: [], |
| 1582 | assistantMessageId: MessageId.makeUnsafe("assistant-keep"), | 1582 | assistantMessageId: MessageId.make("assistant-keep"), |
| 1583 | completedAt: "2026-02-26T12:00:02.000Z", | 1583 | completedAt: "2026-02-26T12:00:02.000Z", |
| 1584 | }, | 1584 | }, |
| 1585 | }); | 1585 | }); |
| 1586 | 1586 | ||
| 1587 | yield* appendAndProject({ | 1587 | yield* appendAndProject({ |
| 1588 | type: "thread.message-sent", | 1588 | type: "thread.message-sent", |
| 1589 | eventId: EventId.makeUnsafe("evt-revert-4"), | 1589 | eventId: EventId.make("evt-revert-4"), |
| 1590 | aggregateKind: "thread", | 1590 | aggregateKind: "thread", |
| 1591 | aggregateId: ThreadId.makeUnsafe("thread-revert"), | 1591 | aggregateId: ThreadId.make("thread-revert"), |
| 1592 | occurredAt: "2026-02-26T12:00:02.100Z", | 1592 | occurredAt: "2026-02-26T12:00:02.100Z", |
| 1593 | commandId: CommandId.makeUnsafe("cmd-revert-4"), | 1593 | commandId: CommandId.make("cmd-revert-4"), |
| 1594 | causationEventId: null, | 1594 | causationEventId: null, |
| 1595 | correlationId: CorrelationId.makeUnsafe("cmd-revert-4"), | 1595 | correlationId: CorrelationId.make("cmd-revert-4"), |
| 1596 | metadata: {}, | 1596 | metadata: {}, |
| 1597 | payload: { | 1597 | payload: { |
| 1598 | threadId: ThreadId.makeUnsafe("thread-revert"), | 1598 | threadId: ThreadId.make("thread-revert"), |
| 1599 | messageId: MessageId.makeUnsafe("assistant-keep"), | 1599 | messageId: MessageId.make("assistant-keep"), |
| 1600 | role: "assistant", | 1600 | role: "assistant", |
| 1601 | text: "kept", | 1601 | text: "kept", |
| 1602 | turnId: TurnId.makeUnsafe("turn-1"), | 1602 | turnId: TurnId.make("turn-1"), |
| 1603 | streaming: false, | 1603 | streaming: false, |
| 1604 | createdAt: "2026-02-26T12:00:02.100Z", | 1604 | createdAt: "2026-02-26T12:00:02.100Z", |
| 1605 | updatedAt: "2026-02-26T12:00:02.100Z", | 1605 | updatedAt: "2026-02-26T12:00:02.100Z", |
| ... | @@ -1608,42 +1608,42 @@ it.layer(BaseTestLayer)("OrchestrationProjectionPipeline", (it) => { | ... | @@ -1608,42 +1608,42 @@ it.layer(BaseTestLayer)("OrchestrationProjectionPipeline", (it) => { |
| 1608 | 1608 | ||
| 1609 | yield* appendAndProject({ | 1609 | yield* appendAndProject({ |
| 1610 | type: "thread.turn-diff-completed", | 1610 | type: "thread.turn-diff-completed", |
| 1611 | eventId: EventId.makeUnsafe("evt-revert-5"), | 1611 | eventId: EventId.make("evt-revert-5"), |
| 1612 | aggregateKind: "thread", | 1612 | aggregateKind: "thread", |
| 1613 | aggregateId: ThreadId.makeUnsafe("thread-revert"), | 1613 | aggregateId: ThreadId.make("thread-revert"), |
| 1614 | occurredAt: "2026-02-26T12:00:03.000Z", | 1614 | occurredAt: "2026-02-26T12:00:03.000Z", |
| 1615 | commandId: CommandId.makeUnsafe("cmd-revert-5"), | 1615 | commandId: CommandId.make("cmd-revert-5"), |
| 1616 | causationEventId: null, | 1616 | causationEventId: null, |
| 1617 | correlationId: CorrelationId.makeUnsafe("cmd-revert-5"), | 1617 | correlationId: CorrelationId.make("cmd-revert-5"), |
| 1618 | metadata: {}, | 1618 | metadata: {}, |
| 1619 | payload: { | 1619 | payload: { |
| 1620 | threadId: ThreadId.makeUnsafe("thread-revert"), | 1620 | threadId: ThreadId.make("thread-revert"), |
| 1621 | turnId: TurnId.makeUnsafe("turn-2"), | 1621 | turnId: TurnId.make("turn-2"), |
| 1622 | checkpointTurnCount: 2, | 1622 | checkpointTurnCount: 2, |
| 1623 | checkpointRef: CheckpointRef.makeUnsafe("refs/t3/checkpoints/thread-revert/turn/2"), | 1623 | checkpointRef: CheckpointRef.make("refs/t3/checkpoints/thread-revert/turn/2"), |
| 1624 | status: "ready", | 1624 | status: "ready", |
| 1625 | files: [], | 1625 | files: [], |
| 1626 | assistantMessageId: MessageId.makeUnsafe("assistant-remove"), | 1626 | assistantMessageId: MessageId.make("assistant-remove"), |
| 1627 | completedAt: "2026-02-26T12:00:03.000Z", | 1627 | completedAt: "2026-02-26T12:00:03.000Z", |
| 1628 | }, | 1628 | }, |
| 1629 | }); | 1629 | }); |
| 1630 | 1630 | ||
| 1631 | yield* appendAndProject({ | 1631 | yield* appendAndProject({ |
| 1632 | type: "thread.message-sent", | 1632 | type: "thread.message-sent", |
| 1633 | eventId: EventId.makeUnsafe("evt-revert-6"), | 1633 | eventId: EventId.make("evt-revert-6"), |
| 1634 | aggregateKind: "thread", | 1634 | aggregateKind: "thread", |
| 1635 | aggregateId: ThreadId.makeUnsafe("thread-revert"), | 1635 | aggregateId: ThreadId.make("thread-revert"), |
| 1636 | occurredAt: "2026-02-26T12:00:03.050Z", | 1636 | occurredAt: "2026-02-26T12:00:03.050Z", |
| 1637 | commandId: CommandId.makeUnsafe("cmd-revert-6"), | 1637 | commandId: CommandId.make("cmd-revert-6"), |
| 1638 | causationEventId: null, | 1638 | causationEventId: null, |
| 1639 | correlationId: CorrelationId.makeUnsafe("cmd-revert-6"), | 1639 | correlationId: CorrelationId.make("cmd-revert-6"), |
| 1640 | metadata: {}, | 1640 | metadata: {}, |
| 1641 | payload: { | 1641 | payload: { |
| 1642 | threadId: ThreadId.makeUnsafe("thread-revert"), | 1642 | threadId: ThreadId.make("thread-revert"), |
| 1643 | messageId: MessageId.makeUnsafe("user-remove"), | 1643 | messageId: MessageId.make("user-remove"), |
| 1644 | role: "user", | 1644 | role: "user", |
| 1645 | text: "removed", | 1645 | text: "removed", |
| 1646 | turnId: TurnId.makeUnsafe("turn-2"), | 1646 | turnId: TurnId.make("turn-2"), |
| 1647 | streaming: false, | 1647 | streaming: false, |
| 1648 | createdAt: "2026-02-26T12:00:03.050Z", | 1648 | createdAt: "2026-02-26T12:00:03.050Z", |
| 1649 | updatedAt: "2026-02-26T12:00:03.050Z", | 1649 | updatedAt: "2026-02-26T12:00:03.050Z", |
| ... | @@ -1652,20 +1652,20 @@ it.layer(BaseTestLayer)("OrchestrationProjectionPipeline", (it) => { | ... | @@ -1652,20 +1652,20 @@ it.layer(BaseTestLayer)("OrchestrationProjectionPipeline", (it) => { |
| 1652 | 1652 | ||
| 1653 | yield* appendAndProject({ | 1653 | yield* appendAndProject({ |
| 1654 | type: "thread.message-sent", | 1654 | type: "thread.message-sent", |
| 1655 | eventId: EventId.makeUnsafe("evt-revert-7"), | 1655 | eventId: EventId.make("evt-revert-7"), |
| 1656 | aggregateKind: "thread", | 1656 | aggregateKind: "thread", |
| 1657 | aggregateId: ThreadId.makeUnsafe("thread-revert"), | 1657 | aggregateId: ThreadId.make("thread-revert"), |
| 1658 | occurredAt: "2026-02-26T12:00:03.100Z", | 1658 | occurredAt: "2026-02-26T12:00:03.100Z", |
| 1659 | commandId: CommandId.makeUnsafe("cmd-revert-7"), | 1659 | commandId: CommandId.make("cmd-revert-7"), |
| 1660 | causationEventId: null, | 1660 | causationEventId: null, |
| 1661 | correlationId: CorrelationId.makeUnsafe("cmd-revert-7"), | 1661 | correlationId: CorrelationId.make("cmd-revert-7"), |
| 1662 | metadata: {}, | 1662 | metadata: {}, |
| 1663 | payload: { | 1663 | payload: { |
| 1664 | threadId: ThreadId.makeUnsafe("thread-revert"), | 1664 | threadId: ThreadId.make("thread-revert"), |
| 1665 | messageId: MessageId.makeUnsafe("assistant-remove"), | 1665 | messageId: MessageId.make("assistant-remove"), |
| 1666 | role: "assistant", | 1666 | role: "assistant", |
| 1667 | text: "removed", | 1667 | text: "removed", |
| 1668 | turnId: TurnId.makeUnsafe("turn-2"), | 1668 | turnId: TurnId.make("turn-2"), |
| 1669 | streaming: false, | 1669 | streaming: false, |
| 1670 | createdAt: "2026-02-26T12:00:03.100Z", | 1670 | createdAt: "2026-02-26T12:00:03.100Z", |
| 1671 | updatedAt: "2026-02-26T12:00:03.100Z", | 1671 | updatedAt: "2026-02-26T12:00:03.100Z", |
| ... | @@ -1674,16 +1674,16 @@ it.layer(BaseTestLayer)("OrchestrationProjectionPipeline", (it) => { | ... | @@ -1674,16 +1674,16 @@ it.layer(BaseTestLayer)("OrchestrationProjectionPipeline", (it) => { |
| 1674 | 1674 | ||
| 1675 | yield* appendAndProject({ | 1675 | yield* appendAndProject({ |
| 1676 | type: "thread.reverted", | 1676 | type: "thread.reverted", |
| 1677 | eventId: EventId.makeUnsafe("evt-revert-8"), | 1677 | eventId: EventId.make("evt-revert-8"), |
| 1678 | aggregateKind: "thread", | 1678 | aggregateKind: "thread", |
| 1679 | aggregateId: ThreadId.makeUnsafe("thread-revert"), | 1679 | aggregateId: ThreadId.make("thread-revert"), |
| 1680 | occurredAt: "2026-02-26T12:00:04.000Z", | 1680 | occurredAt: "2026-02-26T12:00:04.000Z", |
| 1681 | commandId: CommandId.makeUnsafe("cmd-revert-8"), | 1681 | commandId: CommandId.make("cmd-revert-8"), |
| 1682 | causationEventId: null, | 1682 | causationEventId: null, |
| 1683 | correlationId: CorrelationId.makeUnsafe("cmd-revert-8"), | 1683 | correlationId: CorrelationId.make("cmd-revert-8"), |
| 1684 | metadata: {}, | 1684 | metadata: {}, |
| 1685 | payload: { | 1685 | payload: { |
| 1686 | threadId: ThreadId.makeUnsafe("thread-revert"), | 1686 | threadId: ThreadId.make("thread-revert"), |
| 1687 | turnCount: 1, | 1687 | turnCount: 1, |
| 1688 | }, | 1688 | }, |
| 1689 | }); | 1689 | }); |
| ... | @@ -1725,10 +1725,10 @@ it.effect("restores pending turn-start metadata across projection pipeline resta | ... | @@ -1725,10 +1725,10 @@ it.effect("restores pending turn-start metadata across projection pipeline resta |
| 1725 | Layer.provideMerge(persistenceLayer), | 1725 | Layer.provideMerge(persistenceLayer), |
| 1726 | ); | 1726 | ); |
| 1727 | 1727 | ||
| 1728 | const threadId = ThreadId.makeUnsafe("thread-restart"); | 1728 | const threadId = ThreadId.make("thread-restart"); |
| 1729 | const turnId = TurnId.makeUnsafe("turn-restart"); | 1729 | const turnId = TurnId.make("turn-restart"); |
| 1730 | const messageId = MessageId.makeUnsafe("message-restart"); | 1730 | const messageId = MessageId.make("message-restart"); |
| 1731 | const sourcePlanThreadId = ThreadId.makeUnsafe("thread-plan-source"); | 1731 | const sourcePlanThreadId = ThreadId.make("thread-plan-source"); |
| 1732 | const sourcePlanId = "plan-source"; | 1732 | const sourcePlanId = "plan-source"; |
| 1733 | const turnStartedAt = "2026-02-26T14:00:00.000Z"; | 1733 | const turnStartedAt = "2026-02-26T14:00:00.000Z"; |
| 1734 | const sessionSetAt = "2026-02-26T14:00:05.000Z"; | 1734 | const sessionSetAt = "2026-02-26T14:00:05.000Z"; |
| ... | @@ -1739,13 +1739,13 @@ it.effect("restores pending turn-start metadata across projection pipeline resta | ... | @@ -1739,13 +1739,13 @@ it.effect("restores pending turn-start metadata across projection pipeline resta |
| 1739 | 1739 | ||
| 1740 | yield* eventStore.append({ | 1740 | yield* eventStore.append({ |
| 1741 | type: "thread.turn-start-requested", | 1741 | type: "thread.turn-start-requested", |
| 1742 | eventId: EventId.makeUnsafe("evt-restart-1"), | 1742 | eventId: EventId.make("evt-restart-1"), |
| 1743 | aggregateKind: "thread", | 1743 | aggregateKind: "thread", |
| 1744 | aggregateId: threadId, | 1744 | aggregateId: threadId, |
| 1745 | occurredAt: turnStartedAt, | 1745 | occurredAt: turnStartedAt, |
| 1746 | commandId: CommandId.makeUnsafe("cmd-restart-1"), | 1746 | commandId: CommandId.make("cmd-restart-1"), |
| 1747 | causationEventId: null, | 1747 | causationEventId: null, |
| 1748 | correlationId: CorrelationId.makeUnsafe("cmd-restart-1"), | 1748 | correlationId: CorrelationId.make("cmd-restart-1"), |
| 1749 | metadata: {}, | 1749 | metadata: {}, |
| 1750 | payload: { | 1750 | payload: { |
| 1751 | threadId, | 1751 | threadId, |
| ... | @@ -1769,13 +1769,13 @@ it.effect("restores pending turn-start metadata across projection pipeline resta | ... | @@ -1769,13 +1769,13 @@ it.effect("restores pending turn-start metadata across projection pipeline resta |
| 1769 | 1769 | ||
| 1770 | yield* eventStore.append({ | 1770 | yield* eventStore.append({ |
| 1771 | type: "thread.session-set", | 1771 | type: "thread.session-set", |
| 1772 | eventId: EventId.makeUnsafe("evt-restart-2"), | 1772 | eventId: EventId.make("evt-restart-2"), |
| 1773 | aggregateKind: "thread", | 1773 | aggregateKind: "thread", |
| 1774 | aggregateId: threadId, | 1774 | aggregateId: threadId, |
| 1775 | occurredAt: sessionSetAt, | 1775 | occurredAt: sessionSetAt, |
| 1776 | commandId: CommandId.makeUnsafe("cmd-restart-2"), | 1776 | commandId: CommandId.make("cmd-restart-2"), |
| 1777 | causationEventId: null, | 1777 | causationEventId: null, |
| 1778 | correlationId: CorrelationId.makeUnsafe("cmd-restart-2"), | 1778 | correlationId: CorrelationId.make("cmd-restart-2"), |
| 1779 | metadata: {}, | 1779 | metadata: {}, |
| 1780 | payload: { | 1780 | payload: { |
| 1781 | threadId, | 1781 | threadId, |
| ... | @@ -1867,8 +1867,8 @@ engineLayer("OrchestrationProjectionPipeline via engine dispatch", (it) => { | ... | @@ -1867,8 +1867,8 @@ engineLayer("OrchestrationProjectionPipeline via engine dispatch", (it) => { |
| 1867 | 1867 | ||
| 1868 | yield* engine.dispatch({ | 1868 | yield* engine.dispatch({ |
| 1869 | type: "project.create", | 1869 | type: "project.create", |
| 1870 | commandId: CommandId.makeUnsafe("cmd-live-project"), | 1870 | commandId: CommandId.make("cmd-live-project"), |
| 1871 | projectId: ProjectId.makeUnsafe("project-live"), | 1871 | projectId: ProjectId.make("project-live"), |
| 1872 | title: "Live Project", | 1872 | title: "Live Project", |
| 1873 | workspaceRoot: "/tmp/project-live", | 1873 | workspaceRoot: "/tmp/project-live", |
| 1874 | defaultModelSelection: { | 1874 | defaultModelSelection: { |
| ... | @@ -1905,8 +1905,8 @@ engineLayer("OrchestrationProjectionPipeline via engine dispatch", (it) => { | ... | @@ -1905,8 +1905,8 @@ engineLayer("OrchestrationProjectionPipeline via engine dispatch", (it) => { |
| 1905 | 1905 | ||
| 1906 | yield* engine.dispatch({ | 1906 | yield* engine.dispatch({ |
| 1907 | type: "project.create", | 1907 | type: "project.create", |
| 1908 | commandId: CommandId.makeUnsafe("cmd-scripts-project-create"), | 1908 | commandId: CommandId.make("cmd-scripts-project-create"), |
| 1909 | projectId: ProjectId.makeUnsafe("project-scripts"), | 1909 | projectId: ProjectId.make("project-scripts"), |
| 1910 | title: "Scripts Project", | 1910 | title: "Scripts Project", |
| 1911 | workspaceRoot: "/tmp/project-scripts", | 1911 | workspaceRoot: "/tmp/project-scripts", |
| 1912 | defaultModelSelection: { | 1912 | defaultModelSelection: { |
| ... | @@ -1918,8 +1918,8 @@ engineLayer("OrchestrationProjectionPipeline via engine dispatch", (it) => { | ... | @@ -1918,8 +1918,8 @@ engineLayer("OrchestrationProjectionPipeline via engine dispatch", (it) => { |
| 1918 | 1918 | ||
| 1919 | yield* engine.dispatch({ | 1919 | yield* engine.dispatch({ |
| 1920 | type: "project.meta.update", | 1920 | type: "project.meta.update", |
| 1921 | commandId: CommandId.makeUnsafe("cmd-scripts-project-update"), | 1921 | commandId: CommandId.make("cmd-scripts-project-update"), |
| 1922 | projectId: ProjectId.makeUnsafe("project-scripts"), | 1922 | projectId: ProjectId.make("project-scripts"), |
| 1923 | scripts: [ | 1923 | scripts: [ |
| 1924 | { | 1924 | { |
| 1925 | id: "script-1", | 1925 | id: "script-1", |
apps/server/src/orchestration/Layers/ProjectionPipeline.ts+1-1| ... | @@ -86,7 +86,7 @@ function extractActivityRequestId(payload: unknown): ApprovalRequestId | null { | ... | @@ -86,7 +86,7 @@ function extractActivityRequestId(payload: unknown): ApprovalRequestId | null { |
| 86 | return null; | 86 | return null; |
| 87 | } | 87 | } |
| 88 | const requestId = (payload as Record<string, unknown>).requestId; | 88 | const requestId = (payload as Record<string, unknown>).requestId; |
| 89 | return typeof requestId === "string" ? ApprovalRequestId.makeUnsafe(requestId) : null; | 89 | return typeof requestId === "string" ? ApprovalRequestId.make(requestId) : null; |
| 90 | } | 90 | } |
| 91 | 91 | ||
| 92 | function retainProjectionMessagesAfterRevert( | 92 | function retainProjectionMessagesAfterRevert( |
apps/server/src/orchestration/Layers/ProjectionSnapshotQuery.test.ts+12-12| ... | @@ -9,11 +9,11 @@ import { ORCHESTRATION_PROJECTOR_NAMES } from "./ProjectionPipeline.ts"; | ... | @@ -9,11 +9,11 @@ import { ORCHESTRATION_PROJECTOR_NAMES } from "./ProjectionPipeline.ts"; |
| 9 | import { OrchestrationProjectionSnapshotQueryLive } from "./ProjectionSnapshotQuery.ts"; | 9 | import { OrchestrationProjectionSnapshotQueryLive } from "./ProjectionSnapshotQuery.ts"; |
| 10 | import { ProjectionSnapshotQuery } from "../Services/ProjectionSnapshotQuery.ts"; | 10 | import { ProjectionSnapshotQuery } from "../Services/ProjectionSnapshotQuery.ts"; |
| 11 | 11 | ||
| 12 | const asProjectId = (value: string): ProjectId => ProjectId.makeUnsafe(value); | 12 | const asProjectId = (value: string): ProjectId => ProjectId.make(value); |
| 13 | const asTurnId = (value: string): TurnId => TurnId.makeUnsafe(value); | 13 | const asTurnId = (value: string): TurnId => TurnId.make(value); |
| 14 | const asMessageId = (value: string): MessageId => MessageId.makeUnsafe(value); | 14 | const asMessageId = (value: string): MessageId => MessageId.make(value); |
| 15 | const asEventId = (value: string): EventId => EventId.makeUnsafe(value); | 15 | const asEventId = (value: string): EventId => EventId.make(value); |
| 16 | const asCheckpointRef = (value: string): CheckpointRef => CheckpointRef.makeUnsafe(value); | 16 | const asCheckpointRef = (value: string): CheckpointRef => CheckpointRef.make(value); |
| 17 | 17 | ||
| 18 | const projectionSnapshotLayer = it.layer( | 18 | const projectionSnapshotLayer = it.layer( |
| 19 | OrchestrationProjectionSnapshotQueryLive.pipe( | 19 | OrchestrationProjectionSnapshotQueryLive.pipe( |
| ... | @@ -259,7 +259,7 @@ projectionSnapshotLayer("ProjectionSnapshotQuery", (it) => { | ... | @@ -259,7 +259,7 @@ projectionSnapshotLayer("ProjectionSnapshotQuery", (it) => { |
| 259 | ]); | 259 | ]); |
| 260 | assert.deepEqual(snapshot.threads, [ | 260 | assert.deepEqual(snapshot.threads, [ |
| 261 | { | 261 | { |
| 262 | id: ThreadId.makeUnsafe("thread-1"), | 262 | id: ThreadId.make("thread-1"), |
| 263 | projectId: asProjectId("project-1"), | 263 | projectId: asProjectId("project-1"), |
| 264 | title: "Thread 1", | 264 | title: "Thread 1", |
| 265 | modelSelection: { | 265 | modelSelection: { |
| ... | @@ -278,7 +278,7 @@ projectionSnapshotLayer("ProjectionSnapshotQuery", (it) => { | ... | @@ -278,7 +278,7 @@ projectionSnapshotLayer("ProjectionSnapshotQuery", (it) => { |
| 278 | completedAt: "2026-02-24T00:00:08.000Z", | 278 | completedAt: "2026-02-24T00:00:08.000Z", |
| 279 | assistantMessageId: asMessageId("message-1"), | 279 | assistantMessageId: asMessageId("message-1"), |
| 280 | sourceProposedPlan: { | 280 | sourceProposedPlan: { |
| 281 | threadId: ThreadId.makeUnsafe("thread-1"), | 281 | threadId: ThreadId.make("thread-1"), |
| 282 | planId: "plan-1", | 282 | planId: "plan-1", |
| 283 | }, | 283 | }, |
| 284 | }, | 284 | }, |
| ... | @@ -303,7 +303,7 @@ projectionSnapshotLayer("ProjectionSnapshotQuery", (it) => { | ... | @@ -303,7 +303,7 @@ projectionSnapshotLayer("ProjectionSnapshotQuery", (it) => { |
| 303 | turnId: asTurnId("turn-1"), | 303 | turnId: asTurnId("turn-1"), |
| 304 | planMarkdown: "# Ship it", | 304 | planMarkdown: "# Ship it", |
| 305 | implementedAt: "2026-02-24T00:00:05.500Z", | 305 | implementedAt: "2026-02-24T00:00:05.500Z", |
| 306 | implementationThreadId: ThreadId.makeUnsafe("thread-2"), | 306 | implementationThreadId: ThreadId.make("thread-2"), |
| 307 | createdAt: "2026-02-24T00:00:05.000Z", | 307 | createdAt: "2026-02-24T00:00:05.000Z", |
| 308 | updatedAt: "2026-02-24T00:00:05.500Z", | 308 | updatedAt: "2026-02-24T00:00:05.500Z", |
| 309 | }, | 309 | }, |
| ... | @@ -331,7 +331,7 @@ projectionSnapshotLayer("ProjectionSnapshotQuery", (it) => { | ... | @@ -331,7 +331,7 @@ projectionSnapshotLayer("ProjectionSnapshotQuery", (it) => { |
| 331 | }, | 331 | }, |
| 332 | ], | 332 | ], |
| 333 | session: { | 333 | session: { |
| 334 | threadId: ThreadId.makeUnsafe("thread-1"), | 334 | threadId: ThreadId.make("thread-1"), |
| 335 | status: "running", | 335 | status: "running", |
| 336 | providerName: "codex", | 336 | providerName: "codex", |
| 337 | runtimeMode: "approval-required", | 337 | runtimeMode: "approval-required", |
| ... | @@ -473,7 +473,7 @@ projectionSnapshotLayer("ProjectionSnapshotQuery", (it) => { | ... | @@ -473,7 +473,7 @@ projectionSnapshotLayer("ProjectionSnapshotQuery", (it) => { |
| 473 | ); | 473 | ); |
| 474 | assert.equal(firstThreadId._tag, "Some"); | 474 | assert.equal(firstThreadId._tag, "Some"); |
| 475 | if (firstThreadId._tag === "Some") { | 475 | if (firstThreadId._tag === "Some") { |
| 476 | assert.equal(firstThreadId.value, ThreadId.makeUnsafe("thread-first")); | 476 | assert.equal(firstThreadId.value, ThreadId.make("thread-first")); |
| 477 | } | 477 | } |
| 478 | }), | 478 | }), |
| 479 | ); | 479 | ); |
| ... | @@ -596,12 +596,12 @@ projectionSnapshotLayer("ProjectionSnapshotQuery", (it) => { | ... | @@ -596,12 +596,12 @@ projectionSnapshotLayer("ProjectionSnapshotQuery", (it) => { |
| 596 | `; | 596 | `; |
| 597 | 597 | ||
| 598 | const context = yield* snapshotQuery.getThreadCheckpointContext( | 598 | const context = yield* snapshotQuery.getThreadCheckpointContext( |
| 599 | ThreadId.makeUnsafe("thread-context"), | 599 | ThreadId.make("thread-context"), |
| 600 | ); | 600 | ); |
| 601 | assert.equal(context._tag, "Some"); | 601 | assert.equal(context._tag, "Some"); |
| 602 | if (context._tag === "Some") { | 602 | if (context._tag === "Some") { |
| 603 | assert.deepEqual(context.value, { | 603 | assert.deepEqual(context.value, { |
| 604 | threadId: ThreadId.makeUnsafe("thread-context"), | 604 | threadId: ThreadId.make("thread-context"), |
| 605 | projectId: asProjectId("project-context"), | 605 | projectId: asProjectId("project-context"), |
| 606 | workspaceRoot: "/tmp/context-workspace", | 606 | workspaceRoot: "/tmp/context-workspace", |
| 607 | worktreePath: "/tmp/context-worktree", | 607 | worktreePath: "/tmp/context-worktree", |
apps/server/src/orchestration/Layers/ProviderCommandReactor.test.ts+138-151| ... | @@ -38,11 +38,10 @@ import { ProviderCommandReactor } from "../Services/ProviderCommandReactor.ts"; | ... | @@ -38,11 +38,10 @@ import { ProviderCommandReactor } from "../Services/ProviderCommandReactor.ts"; |
| 38 | import * as NodeServices from "@effect/platform-node/NodeServices"; | 38 | import * as NodeServices from "@effect/platform-node/NodeServices"; |
| 39 | import { ServerSettingsService } from "../../serverSettings.ts"; | 39 | import { ServerSettingsService } from "../../serverSettings.ts"; |
| 40 | 40 | ||
| 41 | const asProjectId = (value: string): ProjectId => ProjectId.makeUnsafe(value); | 41 | const asProjectId = (value: string): ProjectId => ProjectId.make(value); |
| 42 | const asApprovalRequestId = (value: string): ApprovalRequestId => | 42 | const asApprovalRequestId = (value: string): ApprovalRequestId => ApprovalRequestId.make(value); |
| 43 | ApprovalRequestId.makeUnsafe(value); | 43 | const asMessageId = (value: string): MessageId => MessageId.make(value); |
| 44 | const asMessageId = (value: string): MessageId => MessageId.makeUnsafe(value); | 44 | const asTurnId = (value: string): TurnId => TurnId.make(value); |
| 45 | const asTurnId = (value: string): TurnId => TurnId.makeUnsafe(value); | ||
| 46 | 45 | ||
| 47 | const deriveServerPathsSync = (baseDir: string, devUrl: URL | undefined) => | 46 | const deriveServerPathsSync = (baseDir: string, devUrl: URL | undefined) => |
| 48 | Effect.runSync(deriveServerPaths(baseDir, devUrl).pipe(Effect.provide(NodeServices.layer))); | 47 | Effect.runSync(deriveServerPaths(baseDir, devUrl).pipe(Effect.provide(NodeServices.layer))); |
| ... | @@ -122,8 +121,8 @@ describe("ProviderCommandReactor", () => { | ... | @@ -122,8 +121,8 @@ describe("ProviderCommandReactor", () => { |
| 122 | input !== null && | 121 | input !== null && |
| 123 | "threadId" in input && | 122 | "threadId" in input && |
| 124 | typeof input.threadId === "string" | 123 | typeof input.threadId === "string" |
| 125 | ? ThreadId.makeUnsafe(input.threadId) | 124 | ? ThreadId.make(input.threadId) |
| 126 | : ThreadId.makeUnsafe(`thread-${sessionIndex}`); | 125 | : ThreadId.make(`thread-${sessionIndex}`); |
| 127 | const session: ProviderSession = { | 126 | const session: ProviderSession = { |
| 128 | provider: modelSelection.provider, | 127 | provider: modelSelection.provider, |
| 129 | status: "ready" as const, | 128 | status: "ready" as const, |
| ... | @@ -145,7 +144,7 @@ describe("ProviderCommandReactor", () => { | ... | @@ -145,7 +144,7 @@ describe("ProviderCommandReactor", () => { |
| 145 | }); | 144 | }); |
| 146 | const sendTurn = vi.fn((_: unknown) => | 145 | const sendTurn = vi.fn((_: unknown) => |
| 147 | Effect.succeed({ | 146 | Effect.succeed({ |
| 148 | threadId: ThreadId.makeUnsafe("thread-1"), | 147 | threadId: ThreadId.make("thread-1"), |
| 149 | turnId: asTurnId("turn-1"), | 148 | turnId: asTurnId("turn-1"), |
| 150 | }), | 149 | }), |
| 151 | ); | 150 | ); |
| ... | @@ -247,7 +246,7 @@ describe("ProviderCommandReactor", () => { | ... | @@ -247,7 +246,7 @@ describe("ProviderCommandReactor", () => { |
| 247 | await Effect.runPromise( | 246 | await Effect.runPromise( |
| 248 | engine.dispatch({ | 247 | engine.dispatch({ |
| 249 | type: "project.create", | 248 | type: "project.create", |
| 250 | commandId: CommandId.makeUnsafe("cmd-project-create"), | 249 | commandId: CommandId.make("cmd-project-create"), |
| 251 | projectId: asProjectId("project-1"), | 250 | projectId: asProjectId("project-1"), |
| 252 | title: "Provider Project", | 251 | title: "Provider Project", |
| 253 | workspaceRoot: "/tmp/provider-project", | 252 | workspaceRoot: "/tmp/provider-project", |
| ... | @@ -258,8 +257,8 @@ describe("ProviderCommandReactor", () => { | ... | @@ -258,8 +257,8 @@ describe("ProviderCommandReactor", () => { |
| 258 | await Effect.runPromise( | 257 | await Effect.runPromise( |
| 259 | engine.dispatch({ | 258 | engine.dispatch({ |
| 260 | type: "thread.create", | 259 | type: "thread.create", |
| 261 | commandId: CommandId.makeUnsafe("cmd-thread-create"), | 260 | commandId: CommandId.make("cmd-thread-create"), |
| 262 | threadId: ThreadId.makeUnsafe("thread-1"), | 261 | threadId: ThreadId.make("thread-1"), |
| 263 | projectId: asProjectId("project-1"), | 262 | projectId: asProjectId("project-1"), |
| 264 | title: "Thread", | 263 | title: "Thread", |
| 265 | modelSelection: modelSelection, | 264 | modelSelection: modelSelection, |
| ... | @@ -294,8 +293,8 @@ describe("ProviderCommandReactor", () => { | ... | @@ -294,8 +293,8 @@ describe("ProviderCommandReactor", () => { |
| 294 | await Effect.runPromise( | 293 | await Effect.runPromise( |
| 295 | harness.engine.dispatch({ | 294 | harness.engine.dispatch({ |
| 296 | type: "thread.turn.start", | 295 | type: "thread.turn.start", |
| 297 | commandId: CommandId.makeUnsafe("cmd-turn-start-1"), | 296 | commandId: CommandId.make("cmd-turn-start-1"), |
| 298 | threadId: ThreadId.makeUnsafe("thread-1"), | 297 | threadId: ThreadId.make("thread-1"), |
| 299 | message: { | 298 | message: { |
| 300 | messageId: asMessageId("user-message-1"), | 299 | messageId: asMessageId("user-message-1"), |
| 301 | role: "user", | 300 | role: "user", |
| ... | @@ -310,7 +309,7 @@ describe("ProviderCommandReactor", () => { | ... | @@ -310,7 +309,7 @@ describe("ProviderCommandReactor", () => { |
| 310 | 309 | ||
| 311 | await waitFor(() => harness.startSession.mock.calls.length === 1); | 310 | await waitFor(() => harness.startSession.mock.calls.length === 1); |
| 312 | await waitFor(() => harness.sendTurn.mock.calls.length === 1); | 311 | await waitFor(() => harness.sendTurn.mock.calls.length === 1); |
| 313 | expect(harness.startSession.mock.calls[0]?.[0]).toEqual(ThreadId.makeUnsafe("thread-1")); | 312 | expect(harness.startSession.mock.calls[0]?.[0]).toEqual(ThreadId.make("thread-1")); |
| 314 | expect(harness.startSession.mock.calls[0]?.[1]).toMatchObject({ | 313 | expect(harness.startSession.mock.calls[0]?.[1]).toMatchObject({ |
| 315 | cwd: "/tmp/provider-project", | 314 | cwd: "/tmp/provider-project", |
| 316 | modelSelection: { | 315 | modelSelection: { |
| ... | @@ -321,7 +320,7 @@ describe("ProviderCommandReactor", () => { | ... | @@ -321,7 +320,7 @@ describe("ProviderCommandReactor", () => { |
| 321 | }); | 320 | }); |
| 322 | 321 | ||
| 323 | const readModel = await Effect.runPromise(harness.engine.getReadModel()); | 322 | const readModel = await Effect.runPromise(harness.engine.getReadModel()); |
| 324 | const thread = readModel.threads.find((entry) => entry.id === ThreadId.makeUnsafe("thread-1")); | 323 | const thread = readModel.threads.find((entry) => entry.id === ThreadId.make("thread-1")); |
| 325 | expect(thread?.session?.threadId).toBe("thread-1"); | 324 | expect(thread?.session?.threadId).toBe("thread-1"); |
| 326 | expect(thread?.session?.runtimeMode).toBe("approval-required"); | 325 | expect(thread?.session?.runtimeMode).toBe("approval-required"); |
| 327 | }); | 326 | }); |
| ... | @@ -335,8 +334,8 @@ describe("ProviderCommandReactor", () => { | ... | @@ -335,8 +334,8 @@ describe("ProviderCommandReactor", () => { |
| 335 | await Effect.runPromise( | 334 | await Effect.runPromise( |
| 336 | harness.engine.dispatch({ | 335 | harness.engine.dispatch({ |
| 337 | type: "thread.meta.update", | 336 | type: "thread.meta.update", |
| 338 | commandId: CommandId.makeUnsafe("cmd-thread-title-seed"), | 337 | commandId: CommandId.make("cmd-thread-title-seed"), |
| 339 | threadId: ThreadId.makeUnsafe("thread-1"), | 338 | threadId: ThreadId.make("thread-1"), |
| 340 | title: seededTitle, | 339 | title: seededTitle, |
| 341 | }), | 340 | }), |
| 342 | ); | 341 | ); |
| ... | @@ -344,8 +343,8 @@ describe("ProviderCommandReactor", () => { | ... | @@ -344,8 +343,8 @@ describe("ProviderCommandReactor", () => { |
| 344 | await Effect.runPromise( | 343 | await Effect.runPromise( |
| 345 | harness.engine.dispatch({ | 344 | harness.engine.dispatch({ |
| 346 | type: "thread.turn.start", | 345 | type: "thread.turn.start", |
| 347 | commandId: CommandId.makeUnsafe("cmd-turn-start-title"), | 346 | commandId: CommandId.make("cmd-turn-start-title"), |
| 348 | threadId: ThreadId.makeUnsafe("thread-1"), | 347 | threadId: ThreadId.make("thread-1"), |
| 349 | message: { | 348 | message: { |
| 350 | messageId: asMessageId("user-message-title"), | 349 | messageId: asMessageId("user-message-title"), |
| 351 | role: "user", | 350 | role: "user", |
| ... | @@ -367,12 +366,12 @@ describe("ProviderCommandReactor", () => { | ... | @@ -367,12 +366,12 @@ describe("ProviderCommandReactor", () => { |
| 367 | await waitFor(async () => { | 366 | await waitFor(async () => { |
| 368 | const readModel = await Effect.runPromise(harness.engine.getReadModel()); | 367 | const readModel = await Effect.runPromise(harness.engine.getReadModel()); |
| 369 | return ( | 368 | return ( |
| 370 | readModel.threads.find((entry) => entry.id === ThreadId.makeUnsafe("thread-1"))?.title === | 369 | readModel.threads.find((entry) => entry.id === ThreadId.make("thread-1"))?.title === |
| 371 | "Generated title" | 370 | "Generated title" |
| 372 | ); | 371 | ); |
| 373 | }); | 372 | }); |
| 374 | const readModel = await Effect.runPromise(harness.engine.getReadModel()); | 373 | const readModel = await Effect.runPromise(harness.engine.getReadModel()); |
| 375 | const thread = readModel.threads.find((entry) => entry.id === ThreadId.makeUnsafe("thread-1")); | 374 | const thread = readModel.threads.find((entry) => entry.id === ThreadId.make("thread-1")); |
| 376 | expect(thread?.title).toBe("Generated title"); | 375 | expect(thread?.title).toBe("Generated title"); |
| 377 | }); | 376 | }); |
| 378 | 377 | ||
| ... | @@ -384,8 +383,8 @@ describe("ProviderCommandReactor", () => { | ... | @@ -384,8 +383,8 @@ describe("ProviderCommandReactor", () => { |
| 384 | await Effect.runPromise( | 383 | await Effect.runPromise( |
| 385 | harness.engine.dispatch({ | 384 | harness.engine.dispatch({ |
| 386 | type: "thread.meta.update", | 385 | type: "thread.meta.update", |
| 387 | commandId: CommandId.makeUnsafe("cmd-thread-title-custom"), | 386 | commandId: CommandId.make("cmd-thread-title-custom"), |
| 388 | threadId: ThreadId.makeUnsafe("thread-1"), | 387 | threadId: ThreadId.make("thread-1"), |
| 389 | title: "Keep this custom title", | 388 | title: "Keep this custom title", |
| 390 | }), | 389 | }), |
| 391 | ); | 390 | ); |
| ... | @@ -393,8 +392,8 @@ describe("ProviderCommandReactor", () => { | ... | @@ -393,8 +392,8 @@ describe("ProviderCommandReactor", () => { |
| 393 | await Effect.runPromise( | 392 | await Effect.runPromise( |
| 394 | harness.engine.dispatch({ | 393 | harness.engine.dispatch({ |
| 395 | type: "thread.turn.start", | 394 | type: "thread.turn.start", |
| 396 | commandId: CommandId.makeUnsafe("cmd-turn-start-title-preserve"), | 395 | commandId: CommandId.make("cmd-turn-start-title-preserve"), |
| 397 | threadId: ThreadId.makeUnsafe("thread-1"), | 396 | threadId: ThreadId.make("thread-1"), |
| 398 | message: { | 397 | message: { |
| 399 | messageId: asMessageId("user-message-title-preserve"), | 398 | messageId: asMessageId("user-message-title-preserve"), |
| 400 | role: "user", | 399 | role: "user", |
| ... | @@ -412,7 +411,7 @@ describe("ProviderCommandReactor", () => { | ... | @@ -412,7 +411,7 @@ describe("ProviderCommandReactor", () => { |
| 412 | expect(harness.generateThreadTitle).not.toHaveBeenCalled(); | 411 | expect(harness.generateThreadTitle).not.toHaveBeenCalled(); |
| 413 | 412 | ||
| 414 | const readModel = await Effect.runPromise(harness.engine.getReadModel()); | 413 | const readModel = await Effect.runPromise(harness.engine.getReadModel()); |
| 415 | const thread = readModel.threads.find((entry) => entry.id === ThreadId.makeUnsafe("thread-1")); | 414 | const thread = readModel.threads.find((entry) => entry.id === ThreadId.make("thread-1")); |
| 416 | expect(thread?.title).toBe("Keep this custom title"); | 415 | expect(thread?.title).toBe("Keep this custom title"); |
| 417 | }); | 416 | }); |
| 418 | 417 | ||
| ... | @@ -429,8 +428,8 @@ describe("ProviderCommandReactor", () => { | ... | @@ -429,8 +428,8 @@ describe("ProviderCommandReactor", () => { |
| 429 | await Effect.runPromise( | 428 | await Effect.runPromise( |
| 430 | harness.engine.dispatch({ | 429 | harness.engine.dispatch({ |
| 431 | type: "thread.meta.update", | 430 | type: "thread.meta.update", |
| 432 | commandId: CommandId.makeUnsafe("cmd-thread-title-formatted-seed"), | 431 | commandId: CommandId.make("cmd-thread-title-formatted-seed"), |
| 433 | threadId: ThreadId.makeUnsafe("thread-1"), | 432 | threadId: ThreadId.make("thread-1"), |
| 434 | title: seededTitle, | 433 | title: seededTitle, |
| 435 | }), | 434 | }), |
| 436 | ); | 435 | ); |
| ... | @@ -438,8 +437,8 @@ describe("ProviderCommandReactor", () => { | ... | @@ -438,8 +437,8 @@ describe("ProviderCommandReactor", () => { |
| 438 | await Effect.runPromise( | 437 | await Effect.runPromise( |
| 439 | harness.engine.dispatch({ | 438 | harness.engine.dispatch({ |
| 440 | type: "thread.turn.start", | 439 | type: "thread.turn.start", |
| 441 | commandId: CommandId.makeUnsafe("cmd-turn-start-title-formatted"), | 440 | commandId: CommandId.make("cmd-turn-start-title-formatted"), |
| 442 | threadId: ThreadId.makeUnsafe("thread-1"), | 441 | threadId: ThreadId.make("thread-1"), |
| 443 | message: { | 442 | message: { |
| 444 | messageId: asMessageId("user-message-title-formatted"), | 443 | messageId: asMessageId("user-message-title-formatted"), |
| 445 | role: "user", | 444 | role: "user", |
| ... | @@ -457,13 +456,13 @@ describe("ProviderCommandReactor", () => { | ... | @@ -457,13 +456,13 @@ describe("ProviderCommandReactor", () => { |
| 457 | await waitFor(async () => { | 456 | await waitFor(async () => { |
| 458 | const readModel = await Effect.runPromise(harness.engine.getReadModel()); | 457 | const readModel = await Effect.runPromise(harness.engine.getReadModel()); |
| 459 | return ( | 458 | return ( |
| 460 | readModel.threads.find((entry) => entry.id === ThreadId.makeUnsafe("thread-1"))?.title === | 459 | readModel.threads.find((entry) => entry.id === ThreadId.make("thread-1"))?.title === |
| 461 | "Reconnect spinner resume bug" | 460 | "Reconnect spinner resume bug" |
| 462 | ); | 461 | ); |
| 463 | }); | 462 | }); |
| 464 | 463 | ||
| 465 | const readModel = await Effect.runPromise(harness.engine.getReadModel()); | 464 | const readModel = await Effect.runPromise(harness.engine.getReadModel()); |
| 466 | const thread = readModel.threads.find((entry) => entry.id === ThreadId.makeUnsafe("thread-1")); | 465 | const thread = readModel.threads.find((entry) => entry.id === ThreadId.make("thread-1")); |
| 467 | expect(thread?.title).toBe("Reconnect spinner resume bug"); | 466 | expect(thread?.title).toBe("Reconnect spinner resume bug"); |
| 468 | }); | 467 | }); |
| 469 | 468 | ||
| ... | @@ -474,8 +473,8 @@ describe("ProviderCommandReactor", () => { | ... | @@ -474,8 +473,8 @@ describe("ProviderCommandReactor", () => { |
| 474 | await Effect.runPromise( | 473 | await Effect.runPromise( |
| 475 | harness.engine.dispatch({ | 474 | harness.engine.dispatch({ |
| 476 | type: "thread.meta.update", | 475 | type: "thread.meta.update", |
| 477 | commandId: CommandId.makeUnsafe("cmd-thread-branch"), | 476 | commandId: CommandId.make("cmd-thread-branch"), |
| 478 | threadId: ThreadId.makeUnsafe("thread-1"), | 477 | threadId: ThreadId.make("thread-1"), |
| 479 | branch: "t3code/1234abcd", | 478 | branch: "t3code/1234abcd", |
| 480 | worktreePath: "/tmp/provider-project-worktree", | 479 | worktreePath: "/tmp/provider-project-worktree", |
| 481 | }), | 480 | }), |
| ... | @@ -499,8 +498,8 @@ describe("ProviderCommandReactor", () => { | ... | @@ -499,8 +498,8 @@ describe("ProviderCommandReactor", () => { |
| 499 | await Effect.runPromise( | 498 | await Effect.runPromise( |
| 500 | harness.engine.dispatch({ | 499 | harness.engine.dispatch({ |
| 501 | type: "thread.turn.start", | 500 | type: "thread.turn.start", |
| 502 | commandId: CommandId.makeUnsafe("cmd-turn-start-branch-model"), | 501 | commandId: CommandId.make("cmd-turn-start-branch-model"), |
| 503 | threadId: ThreadId.makeUnsafe("thread-1"), | 502 | threadId: ThreadId.make("thread-1"), |
| 504 | message: { | 503 | message: { |
| 505 | messageId: asMessageId("user-message-branch-model"), | 504 | messageId: asMessageId("user-message-branch-model"), |
| 506 | role: "user", | 505 | role: "user", |
| ... | @@ -526,8 +525,8 @@ describe("ProviderCommandReactor", () => { | ... | @@ -526,8 +525,8 @@ describe("ProviderCommandReactor", () => { |
| 526 | await Effect.runPromise( | 525 | await Effect.runPromise( |
| 527 | harness.engine.dispatch({ | 526 | harness.engine.dispatch({ |
| 528 | type: "thread.turn.start", | 527 | type: "thread.turn.start", |
| 529 | commandId: CommandId.makeUnsafe("cmd-turn-start-fast"), | 528 | commandId: CommandId.make("cmd-turn-start-fast"), |
| 530 | threadId: ThreadId.makeUnsafe("thread-1"), | 529 | threadId: ThreadId.make("thread-1"), |
| 531 | message: { | 530 | message: { |
| 532 | messageId: asMessageId("user-message-fast"), | 531 | messageId: asMessageId("user-message-fast"), |
| 533 | role: "user", | 532 | role: "user", |
| ... | @@ -561,7 +560,7 @@ describe("ProviderCommandReactor", () => { | ... | @@ -561,7 +560,7 @@ describe("ProviderCommandReactor", () => { |
| 561 | }, | 560 | }, |
| 562 | }); | 561 | }); |
| 563 | expect(harness.sendTurn.mock.calls[0]?.[0]).toMatchObject({ | 562 | expect(harness.sendTurn.mock.calls[0]?.[0]).toMatchObject({ |
| 564 | threadId: ThreadId.makeUnsafe("thread-1"), | 563 | threadId: ThreadId.make("thread-1"), |
| 565 | modelSelection: { | 564 | modelSelection: { |
| 566 | provider: "codex", | 565 | provider: "codex", |
| 567 | model: "gpt-5.3-codex", | 566 | model: "gpt-5.3-codex", |
| ... | @@ -582,8 +581,8 @@ describe("ProviderCommandReactor", () => { | ... | @@ -582,8 +581,8 @@ describe("ProviderCommandReactor", () => { |
| 582 | await Effect.runPromise( | 581 | await Effect.runPromise( |
| 583 | harness.engine.dispatch({ | 582 | harness.engine.dispatch({ |
| 584 | type: "thread.turn.start", | 583 | type: "thread.turn.start", |
| 585 | commandId: CommandId.makeUnsafe("cmd-turn-start-claude-effort"), | 584 | commandId: CommandId.make("cmd-turn-start-claude-effort"), |
| 586 | threadId: ThreadId.makeUnsafe("thread-1"), | 585 | threadId: ThreadId.make("thread-1"), |
| 587 | message: { | 586 | message: { |
| 588 | messageId: asMessageId("user-message-claude-effort"), | 587 | messageId: asMessageId("user-message-claude-effort"), |
| 589 | role: "user", | 588 | role: "user", |
| ... | @@ -615,7 +614,7 @@ describe("ProviderCommandReactor", () => { | ... | @@ -615,7 +614,7 @@ describe("ProviderCommandReactor", () => { |
| 615 | }, | 614 | }, |
| 616 | }); | 615 | }); |
| 617 | expect(harness.sendTurn.mock.calls[0]?.[0]).toMatchObject({ | 616 | expect(harness.sendTurn.mock.calls[0]?.[0]).toMatchObject({ |
| 618 | threadId: ThreadId.makeUnsafe("thread-1"), | 617 | threadId: ThreadId.make("thread-1"), |
| 619 | modelSelection: { | 618 | modelSelection: { |
| 620 | provider: "claudeAgent", | 619 | provider: "claudeAgent", |
| 621 | model: "claude-sonnet-4-6", | 620 | model: "claude-sonnet-4-6", |
| ... | @@ -635,8 +634,8 @@ describe("ProviderCommandReactor", () => { | ... | @@ -635,8 +634,8 @@ describe("ProviderCommandReactor", () => { |
| 635 | await Effect.runPromise( | 634 | await Effect.runPromise( |
| 636 | harness.engine.dispatch({ | 635 | harness.engine.dispatch({ |
| 637 | type: "thread.turn.start", | 636 | type: "thread.turn.start", |
| 638 | commandId: CommandId.makeUnsafe("cmd-turn-start-claude-fast-mode"), | 637 | commandId: CommandId.make("cmd-turn-start-claude-fast-mode"), |
| 639 | threadId: ThreadId.makeUnsafe("thread-1"), | 638 | threadId: ThreadId.make("thread-1"), |
| 640 | message: { | 639 | message: { |
| 641 | messageId: asMessageId("user-message-claude-fast-mode"), | 640 | messageId: asMessageId("user-message-claude-fast-mode"), |
| 642 | role: "user", | 641 | role: "user", |
| ... | @@ -668,7 +667,7 @@ describe("ProviderCommandReactor", () => { | ... | @@ -668,7 +667,7 @@ describe("ProviderCommandReactor", () => { |
| 668 | }, | 667 | }, |
| 669 | }); | 668 | }); |
| 670 | expect(harness.sendTurn.mock.calls[0]?.[0]).toMatchObject({ | 669 | expect(harness.sendTurn.mock.calls[0]?.[0]).toMatchObject({ |
| 671 | threadId: ThreadId.makeUnsafe("thread-1"), | 670 | threadId: ThreadId.make("thread-1"), |
| 672 | modelSelection: { | 671 | modelSelection: { |
| 673 | provider: "claudeAgent", | 672 | provider: "claudeAgent", |
| 674 | model: "claude-opus-4-6", | 673 | model: "claude-opus-4-6", |
| ... | @@ -686,8 +685,8 @@ describe("ProviderCommandReactor", () => { | ... | @@ -686,8 +685,8 @@ describe("ProviderCommandReactor", () => { |
| 686 | await Effect.runPromise( | 685 | await Effect.runPromise( |
| 687 | harness.engine.dispatch({ | 686 | harness.engine.dispatch({ |
| 688 | type: "thread.interaction-mode.set", | 687 | type: "thread.interaction-mode.set", |
| 689 | commandId: CommandId.makeUnsafe("cmd-interaction-mode-set-plan"), | 688 | commandId: CommandId.make("cmd-interaction-mode-set-plan"), |
| 690 | threadId: ThreadId.makeUnsafe("thread-1"), | 689 | threadId: ThreadId.make("thread-1"), |
| 691 | interactionMode: "plan", | 690 | interactionMode: "plan", |
| 692 | createdAt: now, | 691 | createdAt: now, |
| 693 | }), | 692 | }), |
| ... | @@ -696,8 +695,8 @@ describe("ProviderCommandReactor", () => { | ... | @@ -696,8 +695,8 @@ describe("ProviderCommandReactor", () => { |
| 696 | await Effect.runPromise( | 695 | await Effect.runPromise( |
| 697 | harness.engine.dispatch({ | 696 | harness.engine.dispatch({ |
| 698 | type: "thread.turn.start", | 697 | type: "thread.turn.start", |
| 699 | commandId: CommandId.makeUnsafe("cmd-turn-start-plan"), | 698 | commandId: CommandId.make("cmd-turn-start-plan"), |
| 700 | threadId: ThreadId.makeUnsafe("thread-1"), | 699 | threadId: ThreadId.make("thread-1"), |
| 701 | message: { | 700 | message: { |
| 702 | messageId: asMessageId("user-message-plan"), | 701 | messageId: asMessageId("user-message-plan"), |
| 703 | role: "user", | 702 | role: "user", |
| ... | @@ -712,7 +711,7 @@ describe("ProviderCommandReactor", () => { | ... | @@ -712,7 +711,7 @@ describe("ProviderCommandReactor", () => { |
| 712 | 711 | ||
| 713 | await waitFor(() => harness.sendTurn.mock.calls.length === 1); | 712 | await waitFor(() => harness.sendTurn.mock.calls.length === 1); |
| 714 | expect(harness.sendTurn.mock.calls[0]?.[0]).toMatchObject({ | 713 | expect(harness.sendTurn.mock.calls[0]?.[0]).toMatchObject({ |
| 715 | threadId: ThreadId.makeUnsafe("thread-1"), | 714 | threadId: ThreadId.make("thread-1"), |
| 716 | interactionMode: "plan", | 715 | interactionMode: "plan", |
| 717 | }); | 716 | }); |
| 718 | }); | 717 | }); |
| ... | @@ -726,8 +725,8 @@ describe("ProviderCommandReactor", () => { | ... | @@ -726,8 +725,8 @@ describe("ProviderCommandReactor", () => { |
| 726 | await Effect.runPromise( | 725 | await Effect.runPromise( |
| 727 | harness.engine.dispatch({ | 726 | harness.engine.dispatch({ |
| 728 | type: "thread.turn.start", | 727 | type: "thread.turn.start", |
| 729 | commandId: CommandId.makeUnsafe("cmd-turn-start-provider-first"), | 728 | commandId: CommandId.make("cmd-turn-start-provider-first"), |
| 730 | threadId: ThreadId.makeUnsafe("thread-1"), | 729 | threadId: ThreadId.make("thread-1"), |
| 731 | message: { | 730 | message: { |
| 732 | messageId: asMessageId("user-message-provider-first"), | 731 | messageId: asMessageId("user-message-provider-first"), |
| 733 | role: "user", | 732 | role: "user", |
| ... | @@ -746,9 +745,7 @@ describe("ProviderCommandReactor", () => { | ... | @@ -746,9 +745,7 @@ describe("ProviderCommandReactor", () => { |
| 746 | 745 | ||
| 747 | await waitFor(async () => { | 746 | await waitFor(async () => { |
| 748 | const readModel = await Effect.runPromise(harness.engine.getReadModel()); | 747 | const readModel = await Effect.runPromise(harness.engine.getReadModel()); |
| 749 | const thread = readModel.threads.find( | 748 | const thread = readModel.threads.find((entry) => entry.id === ThreadId.make("thread-1")); |
| 750 | (entry) => entry.id === ThreadId.makeUnsafe("thread-1"), | ||
| 751 | ); | ||
| 752 | return ( | 749 | return ( |
| 753 | thread?.activities.some((activity) => activity.kind === "provider.turn.start.failed") ?? | 750 | thread?.activities.some((activity) => activity.kind === "provider.turn.start.failed") ?? |
| 754 | false | 751 | false |
| ... | @@ -759,7 +756,7 @@ describe("ProviderCommandReactor", () => { | ... | @@ -759,7 +756,7 @@ describe("ProviderCommandReactor", () => { |
| 759 | expect(harness.sendTurn).not.toHaveBeenCalled(); | 756 | expect(harness.sendTurn).not.toHaveBeenCalled(); |
| 760 | 757 | ||
| 761 | const readModel = await Effect.runPromise(harness.engine.getReadModel()); | 758 | const readModel = await Effect.runPromise(harness.engine.getReadModel()); |
| 762 | const thread = readModel.threads.find((entry) => entry.id === ThreadId.makeUnsafe("thread-1")); | 759 | const thread = readModel.threads.find((entry) => entry.id === ThreadId.make("thread-1")); |
| 763 | expect(thread?.session).toBeNull(); | 760 | expect(thread?.session).toBeNull(); |
| 764 | expect( | 761 | expect( |
| 765 | thread?.activities.find((activity) => activity.kind === "provider.turn.start.failed"), | 762 | thread?.activities.find((activity) => activity.kind === "provider.turn.start.failed"), |
| ... | @@ -778,8 +775,8 @@ describe("ProviderCommandReactor", () => { | ... | @@ -778,8 +775,8 @@ describe("ProviderCommandReactor", () => { |
| 778 | await Effect.runPromise( | 775 | await Effect.runPromise( |
| 779 | harness.engine.dispatch({ | 776 | harness.engine.dispatch({ |
| 780 | type: "thread.turn.start", | 777 | type: "thread.turn.start", |
| 781 | commandId: CommandId.makeUnsafe("cmd-turn-start-unsupported-1"), | 778 | commandId: CommandId.make("cmd-turn-start-unsupported-1"), |
| 782 | threadId: ThreadId.makeUnsafe("thread-1"), | 779 | threadId: ThreadId.make("thread-1"), |
| 783 | message: { | 780 | message: { |
| 784 | messageId: asMessageId("user-message-unsupported-1"), | 781 | messageId: asMessageId("user-message-unsupported-1"), |
| 785 | role: "user", | 782 | role: "user", |
| ... | @@ -797,8 +794,8 @@ describe("ProviderCommandReactor", () => { | ... | @@ -797,8 +794,8 @@ describe("ProviderCommandReactor", () => { |
| 797 | await Effect.runPromise( | 794 | await Effect.runPromise( |
| 798 | harness.engine.dispatch({ | 795 | harness.engine.dispatch({ |
| 799 | type: "thread.turn.start", | 796 | type: "thread.turn.start", |
| 800 | commandId: CommandId.makeUnsafe("cmd-turn-start-unsupported-2"), | 797 | commandId: CommandId.make("cmd-turn-start-unsupported-2"), |
| 801 | threadId: ThreadId.makeUnsafe("thread-1"), | 798 | threadId: ThreadId.make("thread-1"), |
| 802 | message: { | 799 | message: { |
| 803 | messageId: asMessageId("user-message-unsupported-2"), | 800 | messageId: asMessageId("user-message-unsupported-2"), |
| 804 | role: "user", | 801 | role: "user", |
| ... | @@ -814,7 +811,7 @@ describe("ProviderCommandReactor", () => { | ... | @@ -814,7 +811,7 @@ describe("ProviderCommandReactor", () => { |
| 814 | await waitFor(() => harness.sendTurn.mock.calls.length === 2); | 811 | await waitFor(() => harness.sendTurn.mock.calls.length === 2); |
| 815 | 812 | ||
| 816 | expect(harness.sendTurn.mock.calls[1]?.[0]).toMatchObject({ | 813 | expect(harness.sendTurn.mock.calls[1]?.[0]).toMatchObject({ |
| 817 | threadId: ThreadId.makeUnsafe("thread-1"), | 814 | threadId: ThreadId.make("thread-1"), |
| 818 | modelSelection: { | 815 | modelSelection: { |
| 819 | provider: "codex", | 816 | provider: "codex", |
| 820 | model: "gpt-5-codex", | 817 | model: "gpt-5-codex", |
| ... | @@ -829,8 +826,8 @@ describe("ProviderCommandReactor", () => { | ... | @@ -829,8 +826,8 @@ describe("ProviderCommandReactor", () => { |
| 829 | await Effect.runPromise( | 826 | await Effect.runPromise( |
| 830 | harness.engine.dispatch({ | 827 | harness.engine.dispatch({ |
| 831 | type: "thread.turn.start", | 828 | type: "thread.turn.start", |
| 832 | commandId: CommandId.makeUnsafe("cmd-turn-start-unchanged-1"), | 829 | commandId: CommandId.make("cmd-turn-start-unchanged-1"), |
| 833 | threadId: ThreadId.makeUnsafe("thread-1"), | 830 | threadId: ThreadId.make("thread-1"), |
| 834 | message: { | 831 | message: { |
| 835 | messageId: asMessageId("user-message-unchanged-1"), | 832 | messageId: asMessageId("user-message-unchanged-1"), |
| 836 | role: "user", | 833 | role: "user", |
| ... | @@ -849,8 +846,8 @@ describe("ProviderCommandReactor", () => { | ... | @@ -849,8 +846,8 @@ describe("ProviderCommandReactor", () => { |
| 849 | await Effect.runPromise( | 846 | await Effect.runPromise( |
| 850 | harness.engine.dispatch({ | 847 | harness.engine.dispatch({ |
| 851 | type: "thread.turn.start", | 848 | type: "thread.turn.start", |
| 852 | commandId: CommandId.makeUnsafe("cmd-turn-start-unchanged-2"), | 849 | commandId: CommandId.make("cmd-turn-start-unchanged-2"), |
| 853 | threadId: ThreadId.makeUnsafe("thread-1"), | 850 | threadId: ThreadId.make("thread-1"), |
| 854 | message: { | 851 | message: { |
| 855 | messageId: asMessageId("user-message-unchanged-2"), | 852 | messageId: asMessageId("user-message-unchanged-2"), |
| 856 | role: "user", | 853 | role: "user", |
| ... | @@ -877,8 +874,8 @@ describe("ProviderCommandReactor", () => { | ... | @@ -877,8 +874,8 @@ describe("ProviderCommandReactor", () => { |
| 877 | await Effect.runPromise( | 874 | await Effect.runPromise( |
| 878 | harness.engine.dispatch({ | 875 | harness.engine.dispatch({ |
| 879 | type: "thread.turn.start", | 876 | type: "thread.turn.start", |
| 880 | commandId: CommandId.makeUnsafe("cmd-turn-start-claude-effort-1"), | 877 | commandId: CommandId.make("cmd-turn-start-claude-effort-1"), |
| 881 | threadId: ThreadId.makeUnsafe("thread-1"), | 878 | threadId: ThreadId.make("thread-1"), |
| 882 | message: { | 879 | message: { |
| 883 | messageId: asMessageId("user-message-claude-effort-1"), | 880 | messageId: asMessageId("user-message-claude-effort-1"), |
| 884 | role: "user", | 881 | role: "user", |
| ... | @@ -904,8 +901,8 @@ describe("ProviderCommandReactor", () => { | ... | @@ -904,8 +901,8 @@ describe("ProviderCommandReactor", () => { |
| 904 | await Effect.runPromise( | 901 | await Effect.runPromise( |
| 905 | harness.engine.dispatch({ | 902 | harness.engine.dispatch({ |
| 906 | type: "thread.turn.start", | 903 | type: "thread.turn.start", |
| 907 | commandId: CommandId.makeUnsafe("cmd-turn-start-claude-effort-2"), | 904 | commandId: CommandId.make("cmd-turn-start-claude-effort-2"), |
| 908 | threadId: ThreadId.makeUnsafe("thread-1"), | 905 | threadId: ThreadId.make("thread-1"), |
| 909 | message: { | 906 | message: { |
| 910 | messageId: asMessageId("user-message-claude-effort-2"), | 907 | messageId: asMessageId("user-message-claude-effort-2"), |
| 911 | role: "user", | 908 | role: "user", |
| ... | @@ -946,8 +943,8 @@ describe("ProviderCommandReactor", () => { | ... | @@ -946,8 +943,8 @@ describe("ProviderCommandReactor", () => { |
| 946 | await Effect.runPromise( | 943 | await Effect.runPromise( |
| 947 | harness.engine.dispatch({ | 944 | harness.engine.dispatch({ |
| 948 | type: "thread.runtime-mode.set", | 945 | type: "thread.runtime-mode.set", |
| 949 | commandId: CommandId.makeUnsafe("cmd-runtime-mode-set-initial-full-access"), | 946 | commandId: CommandId.make("cmd-runtime-mode-set-initial-full-access"), |
| 950 | threadId: ThreadId.makeUnsafe("thread-1"), | 947 | threadId: ThreadId.make("thread-1"), |
| 951 | runtimeMode: "full-access", | 948 | runtimeMode: "full-access", |
| 952 | createdAt: now, | 949 | createdAt: now, |
| 953 | }), | 950 | }), |
| ... | @@ -956,8 +953,8 @@ describe("ProviderCommandReactor", () => { | ... | @@ -956,8 +953,8 @@ describe("ProviderCommandReactor", () => { |
| 956 | await Effect.runPromise( | 953 | await Effect.runPromise( |
| 957 | harness.engine.dispatch({ | 954 | harness.engine.dispatch({ |
| 958 | type: "thread.turn.start", | 955 | type: "thread.turn.start", |
| 959 | commandId: CommandId.makeUnsafe("cmd-turn-start-runtime-mode-1"), | 956 | commandId: CommandId.make("cmd-turn-start-runtime-mode-1"), |
| 960 | threadId: ThreadId.makeUnsafe("thread-1"), | 957 | threadId: ThreadId.make("thread-1"), |
| 961 | message: { | 958 | message: { |
| 962 | messageId: asMessageId("user-message-runtime-mode-1"), | 959 | messageId: asMessageId("user-message-runtime-mode-1"), |
| 963 | role: "user", | 960 | role: "user", |
| ... | @@ -976,8 +973,8 @@ describe("ProviderCommandReactor", () => { | ... | @@ -976,8 +973,8 @@ describe("ProviderCommandReactor", () => { |
| 976 | await Effect.runPromise( | 973 | await Effect.runPromise( |
| 977 | harness.engine.dispatch({ | 974 | harness.engine.dispatch({ |
| 978 | type: "thread.runtime-mode.set", | 975 | type: "thread.runtime-mode.set", |
| 979 | commandId: CommandId.makeUnsafe("cmd-runtime-mode-set-1"), | 976 | commandId: CommandId.make("cmd-runtime-mode-set-1"), |
| 980 | threadId: ThreadId.makeUnsafe("thread-1"), | 977 | threadId: ThreadId.make("thread-1"), |
| 981 | runtimeMode: "approval-required", | 978 | runtimeMode: "approval-required", |
| 982 | createdAt: now, | 979 | createdAt: now, |
| 983 | }), | 980 | }), |
| ... | @@ -985,17 +982,15 @@ describe("ProviderCommandReactor", () => { | ... | @@ -985,17 +982,15 @@ describe("ProviderCommandReactor", () => { |
| 985 | 982 | ||
| 986 | await waitFor(async () => { | 983 | await waitFor(async () => { |
| 987 | const readModel = await Effect.runPromise(harness.engine.getReadModel()); | 984 | const readModel = await Effect.runPromise(harness.engine.getReadModel()); |
| 988 | const thread = readModel.threads.find( | 985 | const thread = readModel.threads.find((entry) => entry.id === ThreadId.make("thread-1")); |
| 989 | (entry) => entry.id === ThreadId.makeUnsafe("thread-1"), | ||
| 990 | ); | ||
| 991 | return thread?.runtimeMode === "approval-required"; | 986 | return thread?.runtimeMode === "approval-required"; |
| 992 | }); | 987 | }); |
| 993 | await waitFor(() => harness.startSession.mock.calls.length === 2); | 988 | await waitFor(() => harness.startSession.mock.calls.length === 2); |
| 994 | await Effect.runPromise( | 989 | await Effect.runPromise( |
| 995 | harness.engine.dispatch({ | 990 | harness.engine.dispatch({ |
| 996 | type: "thread.turn.start", | 991 | type: "thread.turn.start", |
| 997 | commandId: CommandId.makeUnsafe("cmd-turn-start-runtime-mode-2"), | 992 | commandId: CommandId.make("cmd-turn-start-runtime-mode-2"), |
| 998 | threadId: ThreadId.makeUnsafe("thread-1"), | 993 | threadId: ThreadId.make("thread-1"), |
| 999 | message: { | 994 | message: { |
| 1000 | messageId: asMessageId("user-message-runtime-mode-2"), | 995 | messageId: asMessageId("user-message-runtime-mode-2"), |
| 1001 | role: "user", | 996 | role: "user", |
| ... | @@ -1012,16 +1007,16 @@ describe("ProviderCommandReactor", () => { | ... | @@ -1012,16 +1007,16 @@ describe("ProviderCommandReactor", () => { |
| 1012 | 1007 | ||
| 1013 | expect(harness.stopSession.mock.calls.length).toBe(0); | 1008 | expect(harness.stopSession.mock.calls.length).toBe(0); |
| 1014 | expect(harness.startSession.mock.calls[1]?.[1]).toMatchObject({ | 1009 | expect(harness.startSession.mock.calls[1]?.[1]).toMatchObject({ |
| 1015 | threadId: ThreadId.makeUnsafe("thread-1"), | 1010 | threadId: ThreadId.make("thread-1"), |
| 1016 | resumeCursor: { opaque: "resume-1" }, | 1011 | resumeCursor: { opaque: "resume-1" }, |
| 1017 | runtimeMode: "approval-required", | 1012 | runtimeMode: "approval-required", |
| 1018 | }); | 1013 | }); |
| 1019 | expect(harness.sendTurn.mock.calls[1]?.[0]).toMatchObject({ | 1014 | expect(harness.sendTurn.mock.calls[1]?.[0]).toMatchObject({ |
| 1020 | threadId: ThreadId.makeUnsafe("thread-1"), | 1015 | threadId: ThreadId.make("thread-1"), |
| 1021 | }); | 1016 | }); |
| 1022 | 1017 | ||
| 1023 | const readModel = await Effect.runPromise(harness.engine.getReadModel()); | 1018 | const readModel = await Effect.runPromise(harness.engine.getReadModel()); |
| 1024 | const thread = readModel.threads.find((entry) => entry.id === ThreadId.makeUnsafe("thread-1")); | 1019 | const thread = readModel.threads.find((entry) => entry.id === ThreadId.make("thread-1")); |
| 1025 | expect(thread?.session?.threadId).toBe("thread-1"); | 1020 | expect(thread?.session?.threadId).toBe("thread-1"); |
| 1026 | expect(thread?.session?.runtimeMode).toBe("approval-required"); | 1021 | expect(thread?.session?.runtimeMode).toBe("approval-required"); |
| 1027 | }); | 1022 | }); |
| ... | @@ -1035,10 +1030,10 @@ describe("ProviderCommandReactor", () => { | ... | @@ -1035,10 +1030,10 @@ describe("ProviderCommandReactor", () => { |
| 1035 | await Effect.runPromise( | 1030 | await Effect.runPromise( |
| 1036 | harness.engine.dispatch({ | 1031 | harness.engine.dispatch({ |
| 1037 | type: "thread.session.set", | 1032 | type: "thread.session.set", |
| 1038 | commandId: CommandId.makeUnsafe("cmd-session-set-runtime-mode-claude"), | 1033 | commandId: CommandId.make("cmd-session-set-runtime-mode-claude"), |
| 1039 | threadId: ThreadId.makeUnsafe("thread-1"), | 1034 | threadId: ThreadId.make("thread-1"), |
| 1040 | session: { | 1035 | session: { |
| 1041 | threadId: ThreadId.makeUnsafe("thread-1"), | 1036 | threadId: ThreadId.make("thread-1"), |
| 1042 | status: "ready", | 1037 | status: "ready", |
| 1043 | providerName: "claudeAgent", | 1038 | providerName: "claudeAgent", |
| 1044 | runtimeMode: "full-access", | 1039 | runtimeMode: "full-access", |
| ... | @@ -1053,8 +1048,8 @@ describe("ProviderCommandReactor", () => { | ... | @@ -1053,8 +1048,8 @@ describe("ProviderCommandReactor", () => { |
| 1053 | await Effect.runPromise( | 1048 | await Effect.runPromise( |
| 1054 | harness.engine.dispatch({ | 1049 | harness.engine.dispatch({ |
| 1055 | type: "thread.runtime-mode.set", | 1050 | type: "thread.runtime-mode.set", |
| 1056 | commandId: CommandId.makeUnsafe("cmd-runtime-mode-set-claude-no-options"), | 1051 | commandId: CommandId.make("cmd-runtime-mode-set-claude-no-options"), |
| 1057 | threadId: ThreadId.makeUnsafe("thread-1"), | 1052 | threadId: ThreadId.make("thread-1"), |
| 1058 | runtimeMode: "approval-required", | 1053 | runtimeMode: "approval-required", |
| 1059 | createdAt: now, | 1054 | createdAt: now, |
| 1060 | }), | 1055 | }), |
| ... | @@ -1078,8 +1073,8 @@ describe("ProviderCommandReactor", () => { | ... | @@ -1078,8 +1073,8 @@ describe("ProviderCommandReactor", () => { |
| 1078 | await Effect.runPromise( | 1073 | await Effect.runPromise( |
| 1079 | harness.engine.dispatch({ | 1074 | harness.engine.dispatch({ |
| 1080 | type: "thread.turn.start", | 1075 | type: "thread.turn.start", |
| 1081 | commandId: CommandId.makeUnsafe("cmd-turn-start-provider-switch-1"), | 1076 | commandId: CommandId.make("cmd-turn-start-provider-switch-1"), |
| 1082 | threadId: ThreadId.makeUnsafe("thread-1"), | 1077 | threadId: ThreadId.make("thread-1"), |
| 1083 | message: { | 1078 | message: { |
| 1084 | messageId: asMessageId("user-message-provider-switch-1"), | 1079 | messageId: asMessageId("user-message-provider-switch-1"), |
| 1085 | role: "user", | 1080 | role: "user", |
| ... | @@ -1098,8 +1093,8 @@ describe("ProviderCommandReactor", () => { | ... | @@ -1098,8 +1093,8 @@ describe("ProviderCommandReactor", () => { |
| 1098 | await Effect.runPromise( | 1093 | await Effect.runPromise( |
| 1099 | harness.engine.dispatch({ | 1094 | harness.engine.dispatch({ |
| 1100 | type: "thread.turn.start", | 1095 | type: "thread.turn.start", |
| 1101 | commandId: CommandId.makeUnsafe("cmd-turn-start-provider-switch-2"), | 1096 | commandId: CommandId.make("cmd-turn-start-provider-switch-2"), |
| 1102 | threadId: ThreadId.makeUnsafe("thread-1"), | 1097 | threadId: ThreadId.make("thread-1"), |
| 1103 | message: { | 1098 | message: { |
| 1104 | messageId: asMessageId("user-message-provider-switch-2"), | 1099 | messageId: asMessageId("user-message-provider-switch-2"), |
| 1105 | role: "user", | 1100 | role: "user", |
| ... | @@ -1118,9 +1113,7 @@ describe("ProviderCommandReactor", () => { | ... | @@ -1118,9 +1113,7 @@ describe("ProviderCommandReactor", () => { |
| 1118 | 1113 | ||
| 1119 | await waitFor(async () => { | 1114 | await waitFor(async () => { |
| 1120 | const readModel = await Effect.runPromise(harness.engine.getReadModel()); | 1115 | const readModel = await Effect.runPromise(harness.engine.getReadModel()); |
| 1121 | const thread = readModel.threads.find( | 1116 | const thread = readModel.threads.find((entry) => entry.id === ThreadId.make("thread-1")); |
| 1122 | (entry) => entry.id === ThreadId.makeUnsafe("thread-1"), | ||
| 1123 | ); | ||
| 1124 | return ( | 1117 | return ( |
| 1125 | thread?.activities.some((activity) => activity.kind === "provider.turn.start.failed") ?? | 1118 | thread?.activities.some((activity) => activity.kind === "provider.turn.start.failed") ?? |
| 1126 | false | 1119 | false |
| ... | @@ -1132,7 +1125,7 @@ describe("ProviderCommandReactor", () => { | ... | @@ -1132,7 +1125,7 @@ describe("ProviderCommandReactor", () => { |
| 1132 | expect(harness.stopSession.mock.calls.length).toBe(0); | 1125 | expect(harness.stopSession.mock.calls.length).toBe(0); |
| 1133 | 1126 | ||
| 1134 | const readModel = await Effect.runPromise(harness.engine.getReadModel()); | 1127 | const readModel = await Effect.runPromise(harness.engine.getReadModel()); |
| 1135 | const thread = readModel.threads.find((entry) => entry.id === ThreadId.makeUnsafe("thread-1")); | 1128 | const thread = readModel.threads.find((entry) => entry.id === ThreadId.make("thread-1")); |
| 1136 | expect(thread?.session?.threadId).toBe("thread-1"); | 1129 | expect(thread?.session?.threadId).toBe("thread-1"); |
| 1137 | expect(thread?.session?.providerName).toBe("codex"); | 1130 | expect(thread?.session?.providerName).toBe("codex"); |
| 1138 | expect(thread?.session?.runtimeMode).toBe("approval-required"); | 1131 | expect(thread?.session?.runtimeMode).toBe("approval-required"); |
| ... | @@ -1152,8 +1145,8 @@ describe("ProviderCommandReactor", () => { | ... | @@ -1152,8 +1145,8 @@ describe("ProviderCommandReactor", () => { |
| 1152 | await Effect.runPromise( | 1145 | await Effect.runPromise( |
| 1153 | harness.engine.dispatch({ | 1146 | harness.engine.dispatch({ |
| 1154 | type: "thread.runtime-mode.set", | 1147 | type: "thread.runtime-mode.set", |
| 1155 | commandId: CommandId.makeUnsafe("cmd-runtime-mode-set-initial-full-access-2"), | 1148 | commandId: CommandId.make("cmd-runtime-mode-set-initial-full-access-2"), |
| 1156 | threadId: ThreadId.makeUnsafe("thread-1"), | 1149 | threadId: ThreadId.make("thread-1"), |
| 1157 | runtimeMode: "full-access", | 1150 | runtimeMode: "full-access", |
| 1158 | createdAt: now, | 1151 | createdAt: now, |
| 1159 | }), | 1152 | }), |
| ... | @@ -1162,8 +1155,8 @@ describe("ProviderCommandReactor", () => { | ... | @@ -1162,8 +1155,8 @@ describe("ProviderCommandReactor", () => { |
| 1162 | await Effect.runPromise( | 1155 | await Effect.runPromise( |
| 1163 | harness.engine.dispatch({ | 1156 | harness.engine.dispatch({ |
| 1164 | type: "thread.turn.start", | 1157 | type: "thread.turn.start", |
| 1165 | commandId: CommandId.makeUnsafe("cmd-turn-start-restart-failure-1"), | 1158 | commandId: CommandId.make("cmd-turn-start-restart-failure-1"), |
| 1166 | threadId: ThreadId.makeUnsafe("thread-1"), | 1159 | threadId: ThreadId.make("thread-1"), |
| 1167 | message: { | 1160 | message: { |
| 1168 | messageId: asMessageId("user-message-restart-failure-1"), | 1161 | messageId: asMessageId("user-message-restart-failure-1"), |
| 1169 | role: "user", | 1162 | role: "user", |
| ... | @@ -1186,8 +1179,8 @@ describe("ProviderCommandReactor", () => { | ... | @@ -1186,8 +1179,8 @@ describe("ProviderCommandReactor", () => { |
| 1186 | await Effect.runPromise( | 1179 | await Effect.runPromise( |
| 1187 | harness.engine.dispatch({ | 1180 | harness.engine.dispatch({ |
| 1188 | type: "thread.runtime-mode.set", | 1181 | type: "thread.runtime-mode.set", |
| 1189 | commandId: CommandId.makeUnsafe("cmd-runtime-mode-set-restart-failure"), | 1182 | commandId: CommandId.make("cmd-runtime-mode-set-restart-failure"), |
| 1190 | threadId: ThreadId.makeUnsafe("thread-1"), | 1183 | threadId: ThreadId.make("thread-1"), |
| 1191 | runtimeMode: "approval-required", | 1184 | runtimeMode: "approval-required", |
| 1192 | createdAt: now, | 1185 | createdAt: now, |
| 1193 | }), | 1186 | }), |
| ... | @@ -1195,9 +1188,7 @@ describe("ProviderCommandReactor", () => { | ... | @@ -1195,9 +1188,7 @@ describe("ProviderCommandReactor", () => { |
| 1195 | 1188 | ||
| 1196 | await waitFor(async () => { | 1189 | await waitFor(async () => { |
| 1197 | const readModel = await Effect.runPromise(harness.engine.getReadModel()); | 1190 | const readModel = await Effect.runPromise(harness.engine.getReadModel()); |
| 1198 | const thread = readModel.threads.find( | 1191 | const thread = readModel.threads.find((entry) => entry.id === ThreadId.make("thread-1")); |
| 1199 | (entry) => entry.id === ThreadId.makeUnsafe("thread-1"), | ||
| 1200 | ); | ||
| 1201 | return thread?.runtimeMode === "approval-required"; | 1192 | return thread?.runtimeMode === "approval-required"; |
| 1202 | }); | 1193 | }); |
| 1203 | await waitFor(() => harness.startSession.mock.calls.length === 2); | 1194 | await waitFor(() => harness.startSession.mock.calls.length === 2); |
| ... | @@ -1207,7 +1198,7 @@ describe("ProviderCommandReactor", () => { | ... | @@ -1207,7 +1198,7 @@ describe("ProviderCommandReactor", () => { |
| 1207 | expect(harness.sendTurn.mock.calls.length).toBe(1); | 1198 | expect(harness.sendTurn.mock.calls.length).toBe(1); |
| 1208 | 1199 | ||
| 1209 | const readModel = await Effect.runPromise(harness.engine.getReadModel()); | 1200 | const readModel = await Effect.runPromise(harness.engine.getReadModel()); |
| 1210 | const thread = readModel.threads.find((entry) => entry.id === ThreadId.makeUnsafe("thread-1")); | 1201 | const thread = readModel.threads.find((entry) => entry.id === ThreadId.make("thread-1")); |
| 1211 | expect(thread?.session?.threadId).toBe("thread-1"); | 1202 | expect(thread?.session?.threadId).toBe("thread-1"); |
| 1212 | expect(thread?.session?.runtimeMode).toBe("full-access"); | 1203 | expect(thread?.session?.runtimeMode).toBe("full-access"); |
| 1213 | }); | 1204 | }); |
| ... | @@ -1219,10 +1210,10 @@ describe("ProviderCommandReactor", () => { | ... | @@ -1219,10 +1210,10 @@ describe("ProviderCommandReactor", () => { |
| 1219 | await Effect.runPromise( | 1210 | await Effect.runPromise( |
| 1220 | harness.engine.dispatch({ | 1211 | harness.engine.dispatch({ |
| 1221 | type: "thread.session.set", | 1212 | type: "thread.session.set", |
| 1222 | commandId: CommandId.makeUnsafe("cmd-session-set"), | 1213 | commandId: CommandId.make("cmd-session-set"), |
| 1223 | threadId: ThreadId.makeUnsafe("thread-1"), | 1214 | threadId: ThreadId.make("thread-1"), |
| 1224 | session: { | 1215 | session: { |
| 1225 | threadId: ThreadId.makeUnsafe("thread-1"), | 1216 | threadId: ThreadId.make("thread-1"), |
| 1226 | status: "running", | 1217 | status: "running", |
| 1227 | providerName: "codex", | 1218 | providerName: "codex", |
| 1228 | runtimeMode: "approval-required", | 1219 | runtimeMode: "approval-required", |
| ... | @@ -1237,8 +1228,8 @@ describe("ProviderCommandReactor", () => { | ... | @@ -1237,8 +1228,8 @@ describe("ProviderCommandReactor", () => { |
| 1237 | await Effect.runPromise( | 1228 | await Effect.runPromise( |
| 1238 | harness.engine.dispatch({ | 1229 | harness.engine.dispatch({ |
| 1239 | type: "thread.turn.interrupt", | 1230 | type: "thread.turn.interrupt", |
| 1240 | commandId: CommandId.makeUnsafe("cmd-turn-interrupt"), | 1231 | commandId: CommandId.make("cmd-turn-interrupt"), |
| 1241 | threadId: ThreadId.makeUnsafe("thread-1"), | 1232 | threadId: ThreadId.make("thread-1"), |
| 1242 | turnId: asTurnId("turn-1"), | 1233 | turnId: asTurnId("turn-1"), |
| 1243 | createdAt: now, | 1234 | createdAt: now, |
| 1244 | }), | 1235 | }), |
| ... | @@ -1257,10 +1248,10 @@ describe("ProviderCommandReactor", () => { | ... | @@ -1257,10 +1248,10 @@ describe("ProviderCommandReactor", () => { |
| 1257 | await Effect.runPromise( | 1248 | await Effect.runPromise( |
| 1258 | harness.engine.dispatch({ | 1249 | harness.engine.dispatch({ |
| 1259 | type: "thread.session.set", | 1250 | type: "thread.session.set", |
| 1260 | commandId: CommandId.makeUnsafe("cmd-session-set-for-approval"), | 1251 | commandId: CommandId.make("cmd-session-set-for-approval"), |
| 1261 | threadId: ThreadId.makeUnsafe("thread-1"), | 1252 | threadId: ThreadId.make("thread-1"), |
| 1262 | session: { | 1253 | session: { |
| 1263 | threadId: ThreadId.makeUnsafe("thread-1"), | 1254 | threadId: ThreadId.make("thread-1"), |
| 1264 | status: "running", | 1255 | status: "running", |
| 1265 | providerName: "codex", | 1256 | providerName: "codex", |
| 1266 | runtimeMode: "approval-required", | 1257 | runtimeMode: "approval-required", |
| ... | @@ -1275,8 +1266,8 @@ describe("ProviderCommandReactor", () => { | ... | @@ -1275,8 +1266,8 @@ describe("ProviderCommandReactor", () => { |
| 1275 | await Effect.runPromise( | 1266 | await Effect.runPromise( |
| 1276 | harness.engine.dispatch({ | 1267 | harness.engine.dispatch({ |
| 1277 | type: "thread.approval.respond", | 1268 | type: "thread.approval.respond", |
| 1278 | commandId: CommandId.makeUnsafe("cmd-approval-respond"), | 1269 | commandId: CommandId.make("cmd-approval-respond"), |
| 1279 | threadId: ThreadId.makeUnsafe("thread-1"), | 1270 | threadId: ThreadId.make("thread-1"), |
| 1280 | requestId: asApprovalRequestId("approval-request-1"), | 1271 | requestId: asApprovalRequestId("approval-request-1"), |
| 1281 | decision: "accept", | 1272 | decision: "accept", |
| 1282 | createdAt: now, | 1273 | createdAt: now, |
| ... | @@ -1298,10 +1289,10 @@ describe("ProviderCommandReactor", () => { | ... | @@ -1298,10 +1289,10 @@ describe("ProviderCommandReactor", () => { |
| 1298 | await Effect.runPromise( | 1289 | await Effect.runPromise( |
| 1299 | harness.engine.dispatch({ | 1290 | harness.engine.dispatch({ |
| 1300 | type: "thread.session.set", | 1291 | type: "thread.session.set", |
| 1301 | commandId: CommandId.makeUnsafe("cmd-session-set-for-user-input"), | 1292 | commandId: CommandId.make("cmd-session-set-for-user-input"), |
| 1302 | threadId: ThreadId.makeUnsafe("thread-1"), | 1293 | threadId: ThreadId.make("thread-1"), |
| 1303 | session: { | 1294 | session: { |
| 1304 | threadId: ThreadId.makeUnsafe("thread-1"), | 1295 | threadId: ThreadId.make("thread-1"), |
| 1305 | status: "running", | 1296 | status: "running", |
| 1306 | providerName: "codex", | 1297 | providerName: "codex", |
| 1307 | runtimeMode: "approval-required", | 1298 | runtimeMode: "approval-required", |
| ... | @@ -1316,8 +1307,8 @@ describe("ProviderCommandReactor", () => { | ... | @@ -1316,8 +1307,8 @@ describe("ProviderCommandReactor", () => { |
| 1316 | await Effect.runPromise( | 1307 | await Effect.runPromise( |
| 1317 | harness.engine.dispatch({ | 1308 | harness.engine.dispatch({ |
| 1318 | type: "thread.user-input.respond", | 1309 | type: "thread.user-input.respond", |
| 1319 | commandId: CommandId.makeUnsafe("cmd-user-input-respond"), | 1310 | commandId: CommandId.make("cmd-user-input-respond"), |
| 1320 | threadId: ThreadId.makeUnsafe("thread-1"), | 1311 | threadId: ThreadId.make("thread-1"), |
| 1321 | requestId: asApprovalRequestId("user-input-request-1"), | 1312 | requestId: asApprovalRequestId("user-input-request-1"), |
| 1322 | answers: { | 1313 | answers: { |
| 1323 | sandbox_mode: "workspace-write", | 1314 | sandbox_mode: "workspace-write", |
| ... | @@ -1352,10 +1343,10 @@ describe("ProviderCommandReactor", () => { | ... | @@ -1352,10 +1343,10 @@ describe("ProviderCommandReactor", () => { |
| 1352 | await Effect.runPromise( | 1343 | await Effect.runPromise( |
| 1353 | harness.engine.dispatch({ | 1344 | harness.engine.dispatch({ |
| 1354 | type: "thread.session.set", | 1345 | type: "thread.session.set", |
| 1355 | commandId: CommandId.makeUnsafe("cmd-session-set-for-approval-error"), | 1346 | commandId: CommandId.make("cmd-session-set-for-approval-error"), |
| 1356 | threadId: ThreadId.makeUnsafe("thread-1"), | 1347 | threadId: ThreadId.make("thread-1"), |
| 1357 | session: { | 1348 | session: { |
| 1358 | threadId: ThreadId.makeUnsafe("thread-1"), | 1349 | threadId: ThreadId.make("thread-1"), |
| 1359 | status: "running", | 1350 | status: "running", |
| 1360 | providerName: "codex", | 1351 | providerName: "codex", |
| 1361 | runtimeMode: "approval-required", | 1352 | runtimeMode: "approval-required", |
| ... | @@ -1370,10 +1361,10 @@ describe("ProviderCommandReactor", () => { | ... | @@ -1370,10 +1361,10 @@ describe("ProviderCommandReactor", () => { |
| 1370 | await Effect.runPromise( | 1361 | await Effect.runPromise( |
| 1371 | harness.engine.dispatch({ | 1362 | harness.engine.dispatch({ |
| 1372 | type: "thread.activity.append", | 1363 | type: "thread.activity.append", |
| 1373 | commandId: CommandId.makeUnsafe("cmd-approval-requested"), | 1364 | commandId: CommandId.make("cmd-approval-requested"), |
| 1374 | threadId: ThreadId.makeUnsafe("thread-1"), | 1365 | threadId: ThreadId.make("thread-1"), |
| 1375 | activity: { | 1366 | activity: { |
| 1376 | id: EventId.makeUnsafe("activity-approval-requested"), | 1367 | id: EventId.make("activity-approval-requested"), |
| 1377 | tone: "approval", | 1368 | tone: "approval", |
| 1378 | kind: "approval.requested", | 1369 | kind: "approval.requested", |
| 1379 | summary: "Command approval requested", | 1370 | summary: "Command approval requested", |
| ... | @@ -1391,8 +1382,8 @@ describe("ProviderCommandReactor", () => { | ... | @@ -1391,8 +1382,8 @@ describe("ProviderCommandReactor", () => { |
| 1391 | await Effect.runPromise( | 1382 | await Effect.runPromise( |
| 1392 | harness.engine.dispatch({ | 1383 | harness.engine.dispatch({ |
| 1393 | type: "thread.approval.respond", | 1384 | type: "thread.approval.respond", |
| 1394 | commandId: CommandId.makeUnsafe("cmd-approval-respond-stale"), | 1385 | commandId: CommandId.make("cmd-approval-respond-stale"), |
| 1395 | threadId: ThreadId.makeUnsafe("thread-1"), | 1386 | threadId: ThreadId.make("thread-1"), |
| 1396 | requestId: asApprovalRequestId("approval-request-1"), | 1387 | requestId: asApprovalRequestId("approval-request-1"), |
| 1397 | decision: "acceptForSession", | 1388 | decision: "acceptForSession", |
| 1398 | createdAt: now, | 1389 | createdAt: now, |
| ... | @@ -1401,9 +1392,7 @@ describe("ProviderCommandReactor", () => { | ... | @@ -1401,9 +1392,7 @@ describe("ProviderCommandReactor", () => { |
| 1401 | 1392 | ||
| 1402 | await waitFor(async () => { | 1393 | await waitFor(async () => { |
| 1403 | const readModel = await Effect.runPromise(harness.engine.getReadModel()); | 1394 | const readModel = await Effect.runPromise(harness.engine.getReadModel()); |
| 1404 | const thread = readModel.threads.find( | 1395 | const thread = readModel.threads.find((entry) => entry.id === ThreadId.make("thread-1")); |
| 1405 | (entry) => entry.id === ThreadId.makeUnsafe("thread-1"), | ||
| 1406 | ); | ||
| 1407 | if (!thread) return false; | 1396 | if (!thread) return false; |
| 1408 | return thread.activities.some( | 1397 | return thread.activities.some( |
| 1409 | (activity) => activity.kind === "provider.approval.respond.failed", | 1398 | (activity) => activity.kind === "provider.approval.respond.failed", |
| ... | @@ -1411,7 +1400,7 @@ describe("ProviderCommandReactor", () => { | ... | @@ -1411,7 +1400,7 @@ describe("ProviderCommandReactor", () => { |
| 1411 | }); | 1400 | }); |
| 1412 | 1401 | ||
| 1413 | const readModel = await Effect.runPromise(harness.engine.getReadModel()); | 1402 | const readModel = await Effect.runPromise(harness.engine.getReadModel()); |
| 1414 | const thread = readModel.threads.find((entry) => entry.id === ThreadId.makeUnsafe("thread-1")); | 1403 | const thread = readModel.threads.find((entry) => entry.id === ThreadId.make("thread-1")); |
| 1415 | expect(thread).toBeDefined(); | 1404 | expect(thread).toBeDefined(); |
| 1416 | 1405 | ||
| 1417 | const failureActivity = thread?.activities.find( | 1406 | const failureActivity = thread?.activities.find( |
| ... | @@ -1449,10 +1438,10 @@ describe("ProviderCommandReactor", () => { | ... | @@ -1449,10 +1438,10 @@ describe("ProviderCommandReactor", () => { |
| 1449 | await Effect.runPromise( | 1438 | await Effect.runPromise( |
| 1450 | harness.engine.dispatch({ | 1439 | harness.engine.dispatch({ |
| 1451 | type: "thread.session.set", | 1440 | type: "thread.session.set", |
| 1452 | commandId: CommandId.makeUnsafe("cmd-session-set-for-user-input-error"), | 1441 | commandId: CommandId.make("cmd-session-set-for-user-input-error"), |
| 1453 | threadId: ThreadId.makeUnsafe("thread-1"), | 1442 | threadId: ThreadId.make("thread-1"), |
| 1454 | session: { | 1443 | session: { |
| 1455 | threadId: ThreadId.makeUnsafe("thread-1"), | 1444 | threadId: ThreadId.make("thread-1"), |
| 1456 | status: "running", | 1445 | status: "running", |
| 1457 | providerName: "claudeAgent", | 1446 | providerName: "claudeAgent", |
| 1458 | runtimeMode: "approval-required", | 1447 | runtimeMode: "approval-required", |
| ... | @@ -1467,10 +1456,10 @@ describe("ProviderCommandReactor", () => { | ... | @@ -1467,10 +1456,10 @@ describe("ProviderCommandReactor", () => { |
| 1467 | await Effect.runPromise( | 1456 | await Effect.runPromise( |
| 1468 | harness.engine.dispatch({ | 1457 | harness.engine.dispatch({ |
| 1469 | type: "thread.activity.append", | 1458 | type: "thread.activity.append", |
| 1470 | commandId: CommandId.makeUnsafe("cmd-user-input-requested"), | 1459 | commandId: CommandId.make("cmd-user-input-requested"), |
| 1471 | threadId: ThreadId.makeUnsafe("thread-1"), | 1460 | threadId: ThreadId.make("thread-1"), |
| 1472 | activity: { | 1461 | activity: { |
| 1473 | id: EventId.makeUnsafe("activity-user-input-requested"), | 1462 | id: EventId.make("activity-user-input-requested"), |
| 1474 | tone: "info", | 1463 | tone: "info", |
| 1475 | kind: "user-input.requested", | 1464 | kind: "user-input.requested", |
| 1476 | summary: "User input requested", | 1465 | summary: "User input requested", |
| ... | @@ -1500,8 +1489,8 @@ describe("ProviderCommandReactor", () => { | ... | @@ -1500,8 +1489,8 @@ describe("ProviderCommandReactor", () => { |
| 1500 | await Effect.runPromise( | 1489 | await Effect.runPromise( |
| 1501 | harness.engine.dispatch({ | 1490 | harness.engine.dispatch({ |
| 1502 | type: "thread.user-input.respond", | 1491 | type: "thread.user-input.respond", |
| 1503 | commandId: CommandId.makeUnsafe("cmd-user-input-respond-stale"), | 1492 | commandId: CommandId.make("cmd-user-input-respond-stale"), |
| 1504 | threadId: ThreadId.makeUnsafe("thread-1"), | 1493 | threadId: ThreadId.make("thread-1"), |
| 1505 | requestId: asApprovalRequestId("user-input-request-1"), | 1494 | requestId: asApprovalRequestId("user-input-request-1"), |
| 1506 | answers: { | 1495 | answers: { |
| 1507 | sandbox_mode: "workspace-write", | 1496 | sandbox_mode: "workspace-write", |
| ... | @@ -1512,9 +1501,7 @@ describe("ProviderCommandReactor", () => { | ... | @@ -1512,9 +1501,7 @@ describe("ProviderCommandReactor", () => { |
| 1512 | 1501 | ||
| 1513 | await waitFor(async () => { | 1502 | await waitFor(async () => { |
| 1514 | const readModel = await Effect.runPromise(harness.engine.getReadModel()); | 1503 | const readModel = await Effect.runPromise(harness.engine.getReadModel()); |
| 1515 | const thread = readModel.threads.find( | 1504 | const thread = readModel.threads.find((entry) => entry.id === ThreadId.make("thread-1")); |
| 1516 | (entry) => entry.id === ThreadId.makeUnsafe("thread-1"), | ||
| 1517 | ); | ||
| 1518 | if (!thread) return false; | 1505 | if (!thread) return false; |
| 1519 | return thread.activities.some( | 1506 | return thread.activities.some( |
| 1520 | (activity) => activity.kind === "provider.user-input.respond.failed", | 1507 | (activity) => activity.kind === "provider.user-input.respond.failed", |
| ... | @@ -1522,7 +1509,7 @@ describe("ProviderCommandReactor", () => { | ... | @@ -1522,7 +1509,7 @@ describe("ProviderCommandReactor", () => { |
| 1522 | }); | 1509 | }); |
| 1523 | 1510 | ||
| 1524 | const readModel = await Effect.runPromise(harness.engine.getReadModel()); | 1511 | const readModel = await Effect.runPromise(harness.engine.getReadModel()); |
| 1525 | const thread = readModel.threads.find((entry) => entry.id === ThreadId.makeUnsafe("thread-1")); | 1512 | const thread = readModel.threads.find((entry) => entry.id === ThreadId.make("thread-1")); |
| 1526 | expect(thread).toBeDefined(); | 1513 | expect(thread).toBeDefined(); |
| 1527 | 1514 | ||
| 1528 | const failureActivity = thread?.activities.find( | 1515 | const failureActivity = thread?.activities.find( |
| ... | @@ -1551,10 +1538,10 @@ describe("ProviderCommandReactor", () => { | ... | @@ -1551,10 +1538,10 @@ describe("ProviderCommandReactor", () => { |
| 1551 | await Effect.runPromise( | 1538 | await Effect.runPromise( |
| 1552 | harness.engine.dispatch({ | 1539 | harness.engine.dispatch({ |
| 1553 | type: "thread.session.set", | 1540 | type: "thread.session.set", |
| 1554 | commandId: CommandId.makeUnsafe("cmd-session-set-for-stop"), | 1541 | commandId: CommandId.make("cmd-session-set-for-stop"), |
| 1555 | threadId: ThreadId.makeUnsafe("thread-1"), | 1542 | threadId: ThreadId.make("thread-1"), |
| 1556 | session: { | 1543 | session: { |
| 1557 | threadId: ThreadId.makeUnsafe("thread-1"), | 1544 | threadId: ThreadId.make("thread-1"), |
| 1558 | status: "ready", | 1545 | status: "ready", |
| 1559 | providerName: "codex", | 1546 | providerName: "codex", |
| 1560 | runtimeMode: "approval-required", | 1547 | runtimeMode: "approval-required", |
| ... | @@ -1569,15 +1556,15 @@ describe("ProviderCommandReactor", () => { | ... | @@ -1569,15 +1556,15 @@ describe("ProviderCommandReactor", () => { |
| 1569 | await Effect.runPromise( | 1556 | await Effect.runPromise( |
| 1570 | harness.engine.dispatch({ | 1557 | harness.engine.dispatch({ |
| 1571 | type: "thread.session.stop", | 1558 | type: "thread.session.stop", |
| 1572 | commandId: CommandId.makeUnsafe("cmd-session-stop"), | 1559 | commandId: CommandId.make("cmd-session-stop"), |
| 1573 | threadId: ThreadId.makeUnsafe("thread-1"), | 1560 | threadId: ThreadId.make("thread-1"), |
| 1574 | createdAt: now, | 1561 | createdAt: now, |
| 1575 | }), | 1562 | }), |
| 1576 | ); | 1563 | ); |
| 1577 | 1564 | ||
| 1578 | await waitFor(() => harness.stopSession.mock.calls.length === 1); | 1565 | await waitFor(() => harness.stopSession.mock.calls.length === 1); |
| 1579 | const readModel = await Effect.runPromise(harness.engine.getReadModel()); | 1566 | const readModel = await Effect.runPromise(harness.engine.getReadModel()); |
| 1580 | const thread = readModel.threads.find((entry) => entry.id === ThreadId.makeUnsafe("thread-1")); | 1567 | const thread = readModel.threads.find((entry) => entry.id === ThreadId.make("thread-1")); |
| 1581 | expect(thread?.session).not.toBeNull(); | 1568 | expect(thread?.session).not.toBeNull(); |
| 1582 | expect(thread?.session?.status).toBe("stopped"); | 1569 | expect(thread?.session?.status).toBe("stopped"); |
| 1583 | expect(thread?.session?.threadId).toBe("thread-1"); | 1570 | expect(thread?.session?.threadId).toBe("thread-1"); |
apps/server/src/orchestration/Layers/ProviderCommandReactor.ts+2-2| ... | @@ -67,7 +67,7 @@ const turnStartKeyForEvent = (event: ProviderIntentEvent): string => | ... | @@ -67,7 +67,7 @@ const turnStartKeyForEvent = (event: ProviderIntentEvent): string => |
| 67 | event.commandId !== null ? `command:${event.commandId}` : `event:${event.eventId}`; | 67 | event.commandId !== null ? `command:${event.commandId}` : `event:${event.eventId}`; |
| 68 | 68 | ||
| 69 | const serverCommandId = (tag: string): CommandId => | 69 | const serverCommandId = (tag: string): CommandId => |
| 70 | CommandId.makeUnsafe(`server:${tag}:${crypto.randomUUID()}`); | 70 | CommandId.make(`server:${tag}:${crypto.randomUUID()}`); |
| 71 | 71 | ||
| 72 | const HANDLED_TURN_START_KEY_MAX = 10_000; | 72 | const HANDLED_TURN_START_KEY_MAX = 10_000; |
| 73 | const HANDLED_TURN_START_KEY_TTL = Duration.minutes(30); | 73 | const HANDLED_TURN_START_KEY_TTL = Duration.minutes(30); |
| ... | @@ -186,7 +186,7 @@ const make = Effect.gen(function* () { | ... | @@ -186,7 +186,7 @@ const make = Effect.gen(function* () { |
| 186 | commandId: serverCommandId("provider-failure-activity"), | 186 | commandId: serverCommandId("provider-failure-activity"), |
| 187 | threadId: input.threadId, | 187 | threadId: input.threadId, |
| 188 | activity: { | 188 | activity: { |
| 189 | id: EventId.makeUnsafe(crypto.randomUUID()), | 189 | id: EventId.make(crypto.randomUUID()), |
| 190 | tone: "error", | 190 | tone: "error", |
| 191 | kind: input.kind, | 191 | kind: input.kind, |
| 192 | summary: input.summary, | 192 | summary: input.summary, |
apps/server/src/orchestration/Layers/ProviderRuntimeIngestion.test.ts+40-48| ... | @@ -47,12 +47,12 @@ function makeTestServerSettingsLayer(overrides: Partial<ServerSettings> = {}) { | ... | @@ -47,12 +47,12 @@ function makeTestServerSettingsLayer(overrides: Partial<ServerSettings> = {}) { |
| 47 | return ServerSettingsService.layerTest(overrides); | 47 | return ServerSettingsService.layerTest(overrides); |
| 48 | } | 48 | } |
| 49 | 49 | ||
| 50 | const asProjectId = (value: string): ProjectId => ProjectId.makeUnsafe(value); | 50 | const asProjectId = (value: string): ProjectId => ProjectId.make(value); |
| 51 | const asItemId = (value: string): ProviderItemId => ProviderItemId.makeUnsafe(value); | 51 | const asItemId = (value: string): ProviderItemId => ProviderItemId.make(value); |
| 52 | const asEventId = (value: string): EventId => EventId.makeUnsafe(value); | 52 | const asEventId = (value: string): EventId => EventId.make(value); |
| 53 | const asMessageId = (value: string): MessageId => MessageId.makeUnsafe(value); | 53 | const asMessageId = (value: string): MessageId => MessageId.make(value); |
| 54 | const asThreadId = (value: string): ThreadId => ThreadId.makeUnsafe(value); | 54 | const asThreadId = (value: string): ThreadId => ThreadId.make(value); |
| 55 | const asTurnId = (value: string): TurnId => TurnId.makeUnsafe(value); | 55 | const asTurnId = (value: string): TurnId => TurnId.make(value); |
| 56 | 56 | ||
| 57 | type LegacyProviderRuntimeEvent = { | 57 | type LegacyProviderRuntimeEvent = { |
| 58 | readonly type: string; | 58 | readonly type: string; |
| ... | @@ -227,7 +227,7 @@ describe("ProviderRuntimeIngestion", () => { | ... | @@ -227,7 +227,7 @@ describe("ProviderRuntimeIngestion", () => { |
| 227 | await Effect.runPromise( | 227 | await Effect.runPromise( |
| 228 | engine.dispatch({ | 228 | engine.dispatch({ |
| 229 | type: "project.create", | 229 | type: "project.create", |
| 230 | commandId: CommandId.makeUnsafe("cmd-provider-project-create"), | 230 | commandId: CommandId.make("cmd-provider-project-create"), |
| 231 | projectId: asProjectId("project-1"), | 231 | projectId: asProjectId("project-1"), |
| 232 | title: "Provider Project", | 232 | title: "Provider Project", |
| 233 | workspaceRoot, | 233 | workspaceRoot, |
| ... | @@ -241,8 +241,8 @@ describe("ProviderRuntimeIngestion", () => { | ... | @@ -241,8 +241,8 @@ describe("ProviderRuntimeIngestion", () => { |
| 241 | await Effect.runPromise( | 241 | await Effect.runPromise( |
| 242 | engine.dispatch({ | 242 | engine.dispatch({ |
| 243 | type: "thread.create", | 243 | type: "thread.create", |
| 244 | commandId: CommandId.makeUnsafe("cmd-thread-create"), | 244 | commandId: CommandId.make("cmd-thread-create"), |
| 245 | threadId: ThreadId.makeUnsafe("thread-1"), | 245 | threadId: ThreadId.make("thread-1"), |
| 246 | projectId: asProjectId("project-1"), | 246 | projectId: asProjectId("project-1"), |
| 247 | title: "Thread", | 247 | title: "Thread", |
| 248 | modelSelection: { | 248 | modelSelection: { |
| ... | @@ -259,10 +259,10 @@ describe("ProviderRuntimeIngestion", () => { | ... | @@ -259,10 +259,10 @@ describe("ProviderRuntimeIngestion", () => { |
| 259 | await Effect.runPromise( | 259 | await Effect.runPromise( |
| 260 | engine.dispatch({ | 260 | engine.dispatch({ |
| 261 | type: "thread.session.set", | 261 | type: "thread.session.set", |
| 262 | commandId: CommandId.makeUnsafe("cmd-session-seed"), | 262 | commandId: CommandId.make("cmd-session-seed"), |
| 263 | threadId: ThreadId.makeUnsafe("thread-1"), | 263 | threadId: ThreadId.make("thread-1"), |
| 264 | session: { | 264 | session: { |
| 265 | threadId: ThreadId.makeUnsafe("thread-1"), | 265 | threadId: ThreadId.make("thread-1"), |
| 266 | status: "ready", | 266 | status: "ready", |
| 267 | providerName: "codex", | 267 | providerName: "codex", |
| 268 | runtimeMode: "approval-required", | 268 | runtimeMode: "approval-required", |
| ... | @@ -277,7 +277,7 @@ describe("ProviderRuntimeIngestion", () => { | ... | @@ -277,7 +277,7 @@ describe("ProviderRuntimeIngestion", () => { |
| 277 | provider: "codex", | 277 | provider: "codex", |
| 278 | status: "ready", | 278 | status: "ready", |
| 279 | runtimeMode: "approval-required", | 279 | runtimeMode: "approval-required", |
| 280 | threadId: ThreadId.makeUnsafe("thread-1"), | 280 | threadId: ThreadId.make("thread-1"), |
| 281 | createdAt, | 281 | createdAt, |
| 282 | updatedAt: createdAt, | 282 | updatedAt: createdAt, |
| 283 | }); | 283 | }); |
| ... | @@ -457,9 +457,7 @@ describe("ProviderRuntimeIngestion", () => { | ... | @@ -457,9 +457,7 @@ describe("ProviderRuntimeIngestion", () => { |
| 457 | 457 | ||
| 458 | await harness.drain(); | 458 | await harness.drain(); |
| 459 | const midReadModel = await Effect.runPromise(harness.engine.getReadModel()); | 459 | const midReadModel = await Effect.runPromise(harness.engine.getReadModel()); |
| 460 | const midThread = midReadModel.threads.find( | 460 | const midThread = midReadModel.threads.find((entry) => entry.id === ThreadId.make("thread-1")); |
| 461 | (entry) => entry.id === ThreadId.makeUnsafe("thread-1"), | ||
| 462 | ); | ||
| 463 | expect(midThread?.session?.status).toBe("running"); | 461 | expect(midThread?.session?.status).toBe("running"); |
| 464 | expect(midThread?.session?.activeTurnId).toBe("turn-midturn-lifecycle"); | 462 | expect(midThread?.session?.activeTurnId).toBe("turn-midturn-lifecycle"); |
| 465 | 463 | ||
| ... | @@ -486,10 +484,10 @@ describe("ProviderRuntimeIngestion", () => { | ... | @@ -486,10 +484,10 @@ describe("ProviderRuntimeIngestion", () => { |
| 486 | await Effect.runPromise( | 484 | await Effect.runPromise( |
| 487 | harness.engine.dispatch({ | 485 | harness.engine.dispatch({ |
| 488 | type: "thread.session.set", | 486 | type: "thread.session.set", |
| 489 | commandId: CommandId.makeUnsafe("cmd-session-seed-claude-placeholder"), | 487 | commandId: CommandId.make("cmd-session-seed-claude-placeholder"), |
| 490 | threadId: ThreadId.makeUnsafe("thread-1"), | 488 | threadId: ThreadId.make("thread-1"), |
| 491 | session: { | 489 | session: { |
| 492 | threadId: ThreadId.makeUnsafe("thread-1"), | 490 | threadId: ThreadId.make("thread-1"), |
| 493 | status: "ready", | 491 | status: "ready", |
| 494 | providerName: "claudeAgent", | 492 | providerName: "claudeAgent", |
| 495 | runtimeMode: "approval-required", | 493 | runtimeMode: "approval-required", |
| ... | @@ -564,9 +562,7 @@ describe("ProviderRuntimeIngestion", () => { | ... | @@ -564,9 +562,7 @@ describe("ProviderRuntimeIngestion", () => { |
| 564 | 562 | ||
| 565 | await harness.drain(); | 563 | await harness.drain(); |
| 566 | const midReadModel = await Effect.runPromise(harness.engine.getReadModel()); | 564 | const midReadModel = await Effect.runPromise(harness.engine.getReadModel()); |
| 567 | const midThread = midReadModel.threads.find( | 565 | const midThread = midReadModel.threads.find((entry) => entry.id === ThreadId.make("thread-1")); |
| 568 | (entry) => entry.id === ThreadId.makeUnsafe("thread-1"), | ||
| 569 | ); | ||
| 570 | expect(midThread?.session?.status).toBe("running"); | 566 | expect(midThread?.session?.status).toBe("running"); |
| 571 | expect(midThread?.session?.activeTurnId).toBe("turn-primary"); | 567 | expect(midThread?.session?.activeTurnId).toBe("turn-primary"); |
| 572 | 568 | ||
| ... | @@ -618,9 +614,7 @@ describe("ProviderRuntimeIngestion", () => { | ... | @@ -618,9 +614,7 @@ describe("ProviderRuntimeIngestion", () => { |
| 618 | 614 | ||
| 619 | await harness.drain(); | 615 | await harness.drain(); |
| 620 | const midReadModel = await Effect.runPromise(harness.engine.getReadModel()); | 616 | const midReadModel = await Effect.runPromise(harness.engine.getReadModel()); |
| 621 | const midThread = midReadModel.threads.find( | 617 | const midThread = midReadModel.threads.find((entry) => entry.id === ThreadId.make("thread-1")); |
| 622 | (entry) => entry.id === ThreadId.makeUnsafe("thread-1"), | ||
| 623 | ); | ||
| 624 | expect(midThread?.session?.status).toBe("running"); | 618 | expect(midThread?.session?.status).toBe("running"); |
| 625 | expect(midThread?.session?.activeTurnId).toBe("turn-guarded-main"); | 619 | expect(midThread?.session?.activeTurnId).toBe("turn-guarded-main"); |
| 626 | 620 | ||
| ... | @@ -770,7 +764,7 @@ describe("ProviderRuntimeIngestion", () => { | ... | @@ -770,7 +764,7 @@ describe("ProviderRuntimeIngestion", () => { |
| 770 | await Effect.runPromise( | 764 | await Effect.runPromise( |
| 771 | harness.engine.dispatch({ | 765 | harness.engine.dispatch({ |
| 772 | type: "thread.create", | 766 | type: "thread.create", |
| 773 | commandId: CommandId.makeUnsafe("cmd-thread-create-plan-source"), | 767 | commandId: CommandId.make("cmd-thread-create-plan-source"), |
| 774 | threadId: sourceThreadId, | 768 | threadId: sourceThreadId, |
| 775 | projectId: asProjectId("project-1"), | 769 | projectId: asProjectId("project-1"), |
| 776 | title: "Plan Source", | 770 | title: "Plan Source", |
| ... | @@ -788,7 +782,7 @@ describe("ProviderRuntimeIngestion", () => { | ... | @@ -788,7 +782,7 @@ describe("ProviderRuntimeIngestion", () => { |
| 788 | await Effect.runPromise( | 782 | await Effect.runPromise( |
| 789 | harness.engine.dispatch({ | 783 | harness.engine.dispatch({ |
| 790 | type: "thread.session.set", | 784 | type: "thread.session.set", |
| 791 | commandId: CommandId.makeUnsafe("cmd-session-set-plan-source"), | 785 | commandId: CommandId.make("cmd-session-set-plan-source"), |
| 792 | threadId: sourceThreadId, | 786 | threadId: sourceThreadId, |
| 793 | session: { | 787 | session: { |
| 794 | threadId: sourceThreadId, | 788 | threadId: sourceThreadId, |
| ... | @@ -805,7 +799,7 @@ describe("ProviderRuntimeIngestion", () => { | ... | @@ -805,7 +799,7 @@ describe("ProviderRuntimeIngestion", () => { |
| 805 | await Effect.runPromise( | 799 | await Effect.runPromise( |
| 806 | harness.engine.dispatch({ | 800 | harness.engine.dispatch({ |
| 807 | type: "thread.create", | 801 | type: "thread.create", |
| 808 | commandId: CommandId.makeUnsafe("cmd-thread-create-plan-target"), | 802 | commandId: CommandId.make("cmd-thread-create-plan-target"), |
| 809 | threadId: targetThreadId, | 803 | threadId: targetThreadId, |
| 810 | projectId: asProjectId("project-1"), | 804 | projectId: asProjectId("project-1"), |
| 811 | title: "Plan Target", | 805 | title: "Plan Target", |
| ... | @@ -823,7 +817,7 @@ describe("ProviderRuntimeIngestion", () => { | ... | @@ -823,7 +817,7 @@ describe("ProviderRuntimeIngestion", () => { |
| 823 | await Effect.runPromise( | 817 | await Effect.runPromise( |
| 824 | harness.engine.dispatch({ | 818 | harness.engine.dispatch({ |
| 825 | type: "thread.session.set", | 819 | type: "thread.session.set", |
| 826 | commandId: CommandId.makeUnsafe("cmd-session-set-plan-target"), | 820 | commandId: CommandId.make("cmd-session-set-plan-target"), |
| 827 | threadId: targetThreadId, | 821 | threadId: targetThreadId, |
| 828 | session: { | 822 | session: { |
| 829 | threadId: targetThreadId, | 823 | threadId: targetThreadId, |
| ... | @@ -882,7 +876,7 @@ describe("ProviderRuntimeIngestion", () => { | ... | @@ -882,7 +876,7 @@ describe("ProviderRuntimeIngestion", () => { |
| 882 | await Effect.runPromise( | 876 | await Effect.runPromise( |
| 883 | harness.engine.dispatch({ | 877 | harness.engine.dispatch({ |
| 884 | type: "thread.turn.start", | 878 | type: "thread.turn.start", |
| 885 | commandId: CommandId.makeUnsafe("cmd-turn-start-plan-target"), | 879 | commandId: CommandId.make("cmd-turn-start-plan-target"), |
| 886 | threadId: targetThreadId, | 880 | threadId: targetThreadId, |
| 887 | message: { | 881 | message: { |
| 888 | messageId: asMessageId("msg-plan-target"), | 882 | messageId: asMessageId("msg-plan-target"), |
| ... | @@ -957,7 +951,7 @@ describe("ProviderRuntimeIngestion", () => { | ... | @@ -957,7 +951,7 @@ describe("ProviderRuntimeIngestion", () => { |
| 957 | await Effect.runPromise( | 951 | await Effect.runPromise( |
| 958 | harness.engine.dispatch({ | 952 | harness.engine.dispatch({ |
| 959 | type: "thread.create", | 953 | type: "thread.create", |
| 960 | commandId: CommandId.makeUnsafe("cmd-thread-create-plan-source-guarded"), | 954 | commandId: CommandId.make("cmd-thread-create-plan-source-guarded"), |
| 961 | threadId: sourceThreadId, | 955 | threadId: sourceThreadId, |
| 962 | projectId: asProjectId("project-1"), | 956 | projectId: asProjectId("project-1"), |
| 963 | title: "Plan Source", | 957 | title: "Plan Source", |
| ... | @@ -975,7 +969,7 @@ describe("ProviderRuntimeIngestion", () => { | ... | @@ -975,7 +969,7 @@ describe("ProviderRuntimeIngestion", () => { |
| 975 | await Effect.runPromise( | 969 | await Effect.runPromise( |
| 976 | harness.engine.dispatch({ | 970 | harness.engine.dispatch({ |
| 977 | type: "thread.session.set", | 971 | type: "thread.session.set", |
| 978 | commandId: CommandId.makeUnsafe("cmd-session-set-plan-source-guarded"), | 972 | commandId: CommandId.make("cmd-session-set-plan-source-guarded"), |
| 979 | threadId: sourceThreadId, | 973 | threadId: sourceThreadId, |
| 980 | session: { | 974 | session: { |
| 981 | threadId: sourceThreadId, | 975 | threadId: sourceThreadId, |
| ... | @@ -1051,7 +1045,7 @@ describe("ProviderRuntimeIngestion", () => { | ... | @@ -1051,7 +1045,7 @@ describe("ProviderRuntimeIngestion", () => { |
| 1051 | await Effect.runPromise( | 1045 | await Effect.runPromise( |
| 1052 | harness.engine.dispatch({ | 1046 | harness.engine.dispatch({ |
| 1053 | type: "thread.turn.start", | 1047 | type: "thread.turn.start", |
| 1054 | commandId: CommandId.makeUnsafe("cmd-turn-start-plan-target-guarded"), | 1048 | commandId: CommandId.make("cmd-turn-start-plan-target-guarded"), |
| 1055 | threadId: targetThreadId, | 1049 | threadId: targetThreadId, |
| 1056 | message: { | 1050 | message: { |
| 1057 | messageId: asMessageId("msg-plan-target-guarded"), | 1051 | messageId: asMessageId("msg-plan-target-guarded"), |
| ... | @@ -1110,7 +1104,7 @@ describe("ProviderRuntimeIngestion", () => { | ... | @@ -1110,7 +1104,7 @@ describe("ProviderRuntimeIngestion", () => { |
| 1110 | await Effect.runPromise( | 1104 | await Effect.runPromise( |
| 1111 | harness.engine.dispatch({ | 1105 | harness.engine.dispatch({ |
| 1112 | type: "thread.create", | 1106 | type: "thread.create", |
| 1113 | commandId: CommandId.makeUnsafe("cmd-thread-create-plan-source-unrelated"), | 1107 | commandId: CommandId.make("cmd-thread-create-plan-source-unrelated"), |
| 1114 | threadId: sourceThreadId, | 1108 | threadId: sourceThreadId, |
| 1115 | projectId: asProjectId("project-1"), | 1109 | projectId: asProjectId("project-1"), |
| 1116 | title: "Plan Source", | 1110 | title: "Plan Source", |
| ... | @@ -1128,7 +1122,7 @@ describe("ProviderRuntimeIngestion", () => { | ... | @@ -1128,7 +1122,7 @@ describe("ProviderRuntimeIngestion", () => { |
| 1128 | await Effect.runPromise( | 1122 | await Effect.runPromise( |
| 1129 | harness.engine.dispatch({ | 1123 | harness.engine.dispatch({ |
| 1130 | type: "thread.session.set", | 1124 | type: "thread.session.set", |
| 1131 | commandId: CommandId.makeUnsafe("cmd-session-set-plan-source-unrelated"), | 1125 | commandId: CommandId.make("cmd-session-set-plan-source-unrelated"), |
| 1132 | threadId: sourceThreadId, | 1126 | threadId: sourceThreadId, |
| 1133 | session: { | 1127 | session: { |
| 1134 | threadId: sourceThreadId, | 1128 | threadId: sourceThreadId, |
| ... | @@ -1145,7 +1139,7 @@ describe("ProviderRuntimeIngestion", () => { | ... | @@ -1145,7 +1139,7 @@ describe("ProviderRuntimeIngestion", () => { |
| 1145 | await Effect.runPromise( | 1139 | await Effect.runPromise( |
| 1146 | harness.engine.dispatch({ | 1140 | harness.engine.dispatch({ |
| 1147 | type: "thread.create", | 1141 | type: "thread.create", |
| 1148 | commandId: CommandId.makeUnsafe("cmd-thread-create-plan-target-unrelated"), | 1142 | commandId: CommandId.make("cmd-thread-create-plan-target-unrelated"), |
| 1149 | threadId: targetThreadId, | 1143 | threadId: targetThreadId, |
| 1150 | projectId: asProjectId("project-1"), | 1144 | projectId: asProjectId("project-1"), |
| 1151 | title: "Plan Target", | 1145 | title: "Plan Target", |
| ... | @@ -1163,7 +1157,7 @@ describe("ProviderRuntimeIngestion", () => { | ... | @@ -1163,7 +1157,7 @@ describe("ProviderRuntimeIngestion", () => { |
| 1163 | await Effect.runPromise( | 1157 | await Effect.runPromise( |
| 1164 | harness.engine.dispatch({ | 1158 | harness.engine.dispatch({ |
| 1165 | type: "thread.session.set", | 1159 | type: "thread.session.set", |
| 1166 | commandId: CommandId.makeUnsafe("cmd-session-set-plan-target-unrelated"), | 1160 | commandId: CommandId.make("cmd-session-set-plan-target-unrelated"), |
| 1167 | threadId: targetThreadId, | 1161 | threadId: targetThreadId, |
| 1168 | session: { | 1162 | session: { |
| 1169 | threadId: targetThreadId, | 1163 | threadId: targetThreadId, |
| ... | @@ -1213,7 +1207,7 @@ describe("ProviderRuntimeIngestion", () => { | ... | @@ -1213,7 +1207,7 @@ describe("ProviderRuntimeIngestion", () => { |
| 1213 | await Effect.runPromise( | 1207 | await Effect.runPromise( |
| 1214 | harness.engine.dispatch({ | 1208 | harness.engine.dispatch({ |
| 1215 | type: "thread.turn.start", | 1209 | type: "thread.turn.start", |
| 1216 | commandId: CommandId.makeUnsafe("cmd-turn-start-plan-target-unrelated"), | 1210 | commandId: CommandId.make("cmd-turn-start-plan-target-unrelated"), |
| 1217 | threadId: targetThreadId, | 1211 | threadId: targetThreadId, |
| 1218 | message: { | 1212 | message: { |
| 1219 | messageId: asMessageId("msg-plan-target-unrelated"), | 1213 | messageId: asMessageId("msg-plan-target-unrelated"), |
| ... | @@ -1364,9 +1358,7 @@ describe("ProviderRuntimeIngestion", () => { | ... | @@ -1364,9 +1358,7 @@ describe("ProviderRuntimeIngestion", () => { |
| 1364 | 1358 | ||
| 1365 | await harness.drain(); | 1359 | await harness.drain(); |
| 1366 | const midReadModel = await Effect.runPromise(harness.engine.getReadModel()); | 1360 | const midReadModel = await Effect.runPromise(harness.engine.getReadModel()); |
| 1367 | const midThread = midReadModel.threads.find( | 1361 | const midThread = midReadModel.threads.find((entry) => entry.id === ThreadId.make("thread-1")); |
| 1368 | (entry) => entry.id === ThreadId.makeUnsafe("thread-1"), | ||
| 1369 | ); | ||
| 1370 | expect( | 1362 | expect( |
| 1371 | midThread?.messages.some( | 1363 | midThread?.messages.some( |
| 1372 | (message: ProviderRuntimeTestMessage) => message.id === "assistant:item-buffered", | 1364 | (message: ProviderRuntimeTestMessage) => message.id === "assistant:item-buffered", |
| ... | @@ -1407,8 +1399,8 @@ describe("ProviderRuntimeIngestion", () => { | ... | @@ -1407,8 +1399,8 @@ describe("ProviderRuntimeIngestion", () => { |
| 1407 | await Effect.runPromise( | 1399 | await Effect.runPromise( |
| 1408 | harness.engine.dispatch({ | 1400 | harness.engine.dispatch({ |
| 1409 | type: "thread.turn.start", | 1401 | type: "thread.turn.start", |
| 1410 | commandId: CommandId.makeUnsafe("cmd-turn-start-streaming-mode"), | 1402 | commandId: CommandId.make("cmd-turn-start-streaming-mode"), |
| 1411 | threadId: ThreadId.makeUnsafe("thread-1"), | 1403 | threadId: ThreadId.make("thread-1"), |
| 1412 | message: { | 1404 | message: { |
| 1413 | messageId: asMessageId("message-streaming-mode"), | 1405 | messageId: asMessageId("message-streaming-mode"), |
| 1414 | role: "user", | 1406 | role: "user", |
| ... | @@ -1649,7 +1641,7 @@ describe("ProviderRuntimeIngestion", () => { | ... | @@ -1649,7 +1641,7 @@ describe("ProviderRuntimeIngestion", () => { |
| 1649 | provider: "codex", | 1641 | provider: "codex", |
| 1650 | createdAt: now, | 1642 | createdAt: now, |
| 1651 | threadId: asThreadId("thread-1"), | 1643 | threadId: asThreadId("thread-1"), |
| 1652 | requestId: ApprovalRequestId.makeUnsafe("req-open"), | 1644 | requestId: ApprovalRequestId.make("req-open"), |
| 1653 | payload: { | 1645 | payload: { |
| 1654 | requestType: "command_execution_approval", | 1646 | requestType: "command_execution_approval", |
| 1655 | detail: "pwd", | 1647 | detail: "pwd", |
| ... | @@ -1662,7 +1654,7 @@ describe("ProviderRuntimeIngestion", () => { | ... | @@ -1662,7 +1654,7 @@ describe("ProviderRuntimeIngestion", () => { |
| 1662 | provider: "codex", | 1654 | provider: "codex", |
| 1663 | createdAt: now, | 1655 | createdAt: now, |
| 1664 | threadId: asThreadId("thread-1"), | 1656 | threadId: asThreadId("thread-1"), |
| 1665 | requestId: ApprovalRequestId.makeUnsafe("req-open"), | 1657 | requestId: ApprovalRequestId.make("req-open"), |
| 1666 | payload: { | 1658 | payload: { |
| 1667 | requestType: "command_execution_approval", | 1659 | requestType: "command_execution_approval", |
| 1668 | decision: "accept", | 1660 | decision: "accept", |
| ... | @@ -1681,7 +1673,7 @@ describe("ProviderRuntimeIngestion", () => { | ... | @@ -1681,7 +1673,7 @@ describe("ProviderRuntimeIngestion", () => { |
| 1681 | ); | 1673 | ); |
| 1682 | 1674 | ||
| 1683 | const readModel = await Effect.runPromise(harness.engine.getReadModel()); | 1675 | const readModel = await Effect.runPromise(harness.engine.getReadModel()); |
| 1684 | const thread = readModel.threads.find((entry) => entry.id === ThreadId.makeUnsafe("thread-1")); | 1676 | const thread = readModel.threads.find((entry) => entry.id === ThreadId.make("thread-1")); |
| 1685 | expect(thread).toBeDefined(); | 1677 | expect(thread).toBeDefined(); |
| 1686 | 1678 | ||
| 1687 | const requested = thread?.activities.find( | 1679 | const requested = thread?.activities.find( |
| ... | @@ -2286,7 +2278,7 @@ describe("ProviderRuntimeIngestion", () => { | ... | @@ -2286,7 +2278,7 @@ describe("ProviderRuntimeIngestion", () => { |
| 2286 | createdAt: now, | 2278 | createdAt: now, |
| 2287 | threadId: asThreadId("thread-1"), | 2279 | threadId: asThreadId("thread-1"), |
| 2288 | turnId: asTurnId("turn-user-input"), | 2280 | turnId: asTurnId("turn-user-input"), |
| 2289 | requestId: ApprovalRequestId.makeUnsafe("req-user-input-1"), | 2281 | requestId: ApprovalRequestId.make("req-user-input-1"), |
| 2290 | payload: { | 2282 | payload: { |
| 2291 | questions: [ | 2283 | questions: [ |
| 2292 | { | 2284 | { |
| ... | @@ -2311,7 +2303,7 @@ describe("ProviderRuntimeIngestion", () => { | ... | @@ -2311,7 +2303,7 @@ describe("ProviderRuntimeIngestion", () => { |
| 2311 | createdAt: new Date().toISOString(), | 2303 | createdAt: new Date().toISOString(), |
| 2312 | threadId: asThreadId("thread-1"), | 2304 | threadId: asThreadId("thread-1"), |
| 2313 | turnId: asTurnId("turn-user-input"), | 2305 | turnId: asTurnId("turn-user-input"), |
| 2314 | requestId: ApprovalRequestId.makeUnsafe("req-user-input-1"), | 2306 | requestId: ApprovalRequestId.make("req-user-input-1"), |
| 2315 | payload: { | 2307 | payload: { |
| 2316 | answers: { | 2308 | answers: { |
| 2317 | sandbox_mode: "workspace-write", | 2309 | sandbox_mode: "workspace-write", |
apps/server/src/orchestration/Layers/ProviderRuntimeIngestion.ts+8-10| ... | @@ -30,7 +30,7 @@ import { ServerSettingsService } from "../../serverSettings.ts"; | ... | @@ -30,7 +30,7 @@ import { ServerSettingsService } from "../../serverSettings.ts"; |
| 30 | 30 | ||
| 31 | const providerTurnKey = (threadId: ThreadId, turnId: TurnId) => `${threadId}:${turnId}`; | 31 | const providerTurnKey = (threadId: ThreadId, turnId: TurnId) => `${threadId}:${turnId}`; |
| 32 | const providerCommandId = (event: ProviderRuntimeEvent, tag: string): CommandId => | 32 | const providerCommandId = (event: ProviderRuntimeEvent, tag: string): CommandId => |
| 33 | CommandId.makeUnsafe(`provider:${event.eventId}:${tag}:${crypto.randomUUID()}`); | 33 | CommandId.make(`provider:${event.eventId}:${tag}:${crypto.randomUUID()}`); |
| 34 | 34 | ||
| 35 | const TURN_MESSAGE_IDS_BY_TURN_CACHE_CAPACITY = 10_000; | 35 | const TURN_MESSAGE_IDS_BY_TURN_CACHE_CAPACITY = 10_000; |
| 36 | const TURN_MESSAGE_IDS_BY_TURN_TTL = Duration.minutes(120); | 36 | const TURN_MESSAGE_IDS_BY_TURN_TTL = Duration.minutes(120); |
| ... | @@ -57,11 +57,11 @@ type RuntimeIngestionInput = | ... | @@ -57,11 +57,11 @@ type RuntimeIngestionInput = |
| 57 | }; | 57 | }; |
| 58 | 58 | ||
| 59 | function toTurnId(value: TurnId | string | undefined): TurnId | undefined { | 59 | function toTurnId(value: TurnId | string | undefined): TurnId | undefined { |
| 60 | return value === undefined ? undefined : TurnId.makeUnsafe(String(value)); | 60 | return value === undefined ? undefined : TurnId.make(String(value)); |
| 61 | } | 61 | } |
| 62 | 62 | ||
| 63 | function toApprovalRequestId(value: string | undefined): ApprovalRequestId | undefined { | 63 | function toApprovalRequestId(value: string | undefined): ApprovalRequestId | undefined { |
| 64 | return value === undefined ? undefined : ApprovalRequestId.makeUnsafe(value); | 64 | return value === undefined ? undefined : ApprovalRequestId.make(value); |
| 65 | } | 65 | } |
| 66 | 66 | ||
| 67 | function sameId(left: string | null | undefined, right: string | null | undefined): boolean { | 67 | function sameId(left: string | null | undefined, right: string | null | undefined): boolean { |
| ... | @@ -857,7 +857,7 @@ const make = Effect.fn("make")(function* () { | ... | @@ -857,7 +857,7 @@ const make = Effect.fn("make")(function* () { |
| 857 | 857 | ||
| 858 | yield* orchestrationEngine.dispatch({ | 858 | yield* orchestrationEngine.dispatch({ |
| 859 | type: "thread.proposed-plan.upsert", | 859 | type: "thread.proposed-plan.upsert", |
| 860 | commandId: CommandId.makeUnsafe( | 860 | commandId: CommandId.make( |
| 861 | `provider:source-proposed-plan-implemented:${implementationThreadId}:${crypto.randomUUID()}`, | 861 | `provider:source-proposed-plan-implemented:${implementationThreadId}:${crypto.randomUUID()}`, |
| 862 | ), | 862 | ), |
| 863 | threadId: sourceThread.id, | 863 | threadId: sourceThread.id, |
| ... | @@ -1003,7 +1003,7 @@ const make = Effect.fn("make")(function* () { | ... | @@ -1003,7 +1003,7 @@ const make = Effect.fn("make")(function* () { |
| 1003 | event.type === "turn.proposed.delta" ? event.payload.delta : undefined; | 1003 | event.type === "turn.proposed.delta" ? event.payload.delta : undefined; |
| 1004 | 1004 | ||
| 1005 | if (assistantDelta && assistantDelta.length > 0) { | 1005 | if (assistantDelta && assistantDelta.length > 0) { |
| 1006 | const assistantMessageId = MessageId.makeUnsafe( | 1006 | const assistantMessageId = MessageId.make( |
| 1007 | `assistant:${event.itemId ?? event.turnId ?? event.eventId}`, | 1007 | `assistant:${event.itemId ?? event.turnId ?? event.eventId}`, |
| 1008 | ); | 1008 | ); |
| 1009 | const turnId = toTurnId(event.turnId); | 1009 | const turnId = toTurnId(event.turnId); |
| ... | @@ -1049,9 +1049,7 @@ const make = Effect.fn("make")(function* () { | ... | @@ -1049,9 +1049,7 @@ const make = Effect.fn("make")(function* () { |
| 1049 | const assistantCompletion = | 1049 | const assistantCompletion = |
| 1050 | event.type === "item.completed" && event.payload.itemType === "assistant_message" | 1050 | event.type === "item.completed" && event.payload.itemType === "assistant_message" |
| 1051 | ? { | 1051 | ? { |
| 1052 | messageId: MessageId.makeUnsafe( | 1052 | messageId: MessageId.make(`assistant:${event.itemId ?? event.turnId ?? event.eventId}`), |
| 1053 | `assistant:${event.itemId ?? event.turnId ?? event.eventId}`, | ||
| 1054 | ), | ||
| 1055 | fallbackText: event.payload.detail, | 1053 | fallbackText: event.payload.detail, |
| 1056 | } | 1054 | } |
| 1057 | : undefined; | 1055 | : undefined; |
| ... | @@ -1186,7 +1184,7 @@ const make = Effect.fn("make")(function* () { | ... | @@ -1186,7 +1184,7 @@ const make = Effect.fn("make")(function* () { |
| 1186 | if (thread.checkpoints.some((c) => c.turnId === turnId)) { | 1184 | if (thread.checkpoints.some((c) => c.turnId === turnId)) { |
| 1187 | // Already tracked; no-op. | 1185 | // Already tracked; no-op. |
| 1188 | } else { | 1186 | } else { |
| 1189 | const assistantMessageId = MessageId.makeUnsafe( | 1187 | const assistantMessageId = MessageId.make( |
| 1190 | `assistant:${event.itemId ?? event.turnId ?? event.eventId}`, | 1188 | `assistant:${event.itemId ?? event.turnId ?? event.eventId}`, |
| 1191 | ); | 1189 | ); |
| 1192 | const maxTurnCount = thread.checkpoints.reduce( | 1190 | const maxTurnCount = thread.checkpoints.reduce( |
| ... | @@ -1199,7 +1197,7 @@ const make = Effect.fn("make")(function* () { | ... | @@ -1199,7 +1197,7 @@ const make = Effect.fn("make")(function* () { |
| 1199 | threadId: thread.id, | 1197 | threadId: thread.id, |
| 1200 | turnId, | 1198 | turnId, |
| 1201 | completedAt: now, | 1199 | completedAt: now, |
| 1202 | checkpointRef: CheckpointRef.makeUnsafe(`provider-diff:${event.eventId}`), | 1200 | checkpointRef: CheckpointRef.make(`provider-diff:${event.eventId}`), |
| 1203 | status: "missing", | 1201 | status: "missing", |
| 1204 | files: [], | 1202 | files: [], |
| 1205 | assistantMessageId, | 1203 | assistantMessageId, |
apps/server/src/orchestration/Services/CheckpointReactor.ts+4-5| ... | @@ -6,7 +6,7 @@ | ... | @@ -6,7 +6,7 @@ |
| 6 | * | 6 | * |
| 7 | * @module CheckpointReactor | 7 | * @module CheckpointReactor |
| 8 | */ | 8 | */ |
| 9 | import { ServiceMap } from "effect"; | 9 | import { Context } from "effect"; |
| 10 | import type { Effect, Scope } from "effect"; | 10 | import type { Effect, Scope } from "effect"; |
| 11 | 11 | ||
| 12 | /** | 12 | /** |
| ... | @@ -34,7 +34,6 @@ export interface CheckpointReactorShape { | ... | @@ -34,7 +34,6 @@ export interface CheckpointReactorShape { |
| 34 | /** | 34 | /** |
| 35 | * CheckpointReactor - Service tag for checkpoint reactor workers. | 35 | * CheckpointReactor - Service tag for checkpoint reactor workers. |
| 36 | */ | 36 | */ |
| 37 | export class CheckpointReactor extends ServiceMap.Service< | 37 | export class CheckpointReactor extends Context.Service<CheckpointReactor, CheckpointReactorShape>()( |
| 38 | CheckpointReactor, | 38 | "t3/orchestration/Services/CheckpointReactor", |
| 39 | CheckpointReactorShape | 39 | ) {} |
| 40 | >()("t3/orchestration/Services/CheckpointReactor") {} |
apps/server/src/orchestration/Services/OrchestrationEngine.ts+3-3| ... | @@ -5,7 +5,7 @@ | ... | @@ -5,7 +5,7 @@ |
| 5 | * `OrchestrationEventStore` persistence. It does not own provider process | 5 | * `OrchestrationEventStore` persistence. It does not own provider process |
| 6 | * management or transport concerns (e.g. websocket request parsing). | 6 | * management or transport concerns (e.g. websocket request parsing). |
| 7 | * | 7 | * |
| 8 | * Uses Effect `ServiceMap.Service` for dependency injection. Command dispatch, | 8 | * Uses Effect `Context.Service` for dependency injection. Command dispatch, |
| 9 | * replay, and unknown-input decoding all return typed domain errors. | 9 | * replay, and unknown-input decoding all return typed domain errors. |
| 10 | * | 10 | * |
| 11 | * @module OrchestrationEngineService | 11 | * @module OrchestrationEngineService |
| ... | @@ -15,7 +15,7 @@ import type { | ... | @@ -15,7 +15,7 @@ import type { |
| 15 | OrchestrationEvent, | 15 | OrchestrationEvent, |
| 16 | OrchestrationReadModel, | 16 | OrchestrationReadModel, |
| 17 | } from "@t3tools/contracts"; | 17 | } from "@t3tools/contracts"; |
| 18 | import { ServiceMap } from "effect"; | 18 | import { Context } from "effect"; |
| 19 | import type { Effect, Stream } from "effect"; | 19 | import type { Effect, Stream } from "effect"; |
| 20 | 20 | ||
| 21 | import type { OrchestrationDispatchError } from "../Errors.ts"; | 21 | import type { OrchestrationDispatchError } from "../Errors.ts"; |
| ... | @@ -74,7 +74,7 @@ export interface OrchestrationEngineShape { | ... | @@ -74,7 +74,7 @@ export interface OrchestrationEngineShape { |
| 74 | * }) | 74 | * }) |
| 75 | * ``` | 75 | * ``` |
| 76 | */ | 76 | */ |
| 77 | export class OrchestrationEngineService extends ServiceMap.Service< | 77 | export class OrchestrationEngineService extends Context.Service< |
| 78 | OrchestrationEngineService, | 78 | OrchestrationEngineService, |
| 79 | OrchestrationEngineShape | 79 | OrchestrationEngineShape |
| 80 | >()("t3/orchestration/Services/OrchestrationEngine/OrchestrationEngineService") {} | 80 | >()("t3/orchestration/Services/OrchestrationEngine/OrchestrationEngineService") {} |
apps/server/src/orchestration/Services/OrchestrationReactor.ts+2-2| ... | @@ -6,7 +6,7 @@ | ... | @@ -6,7 +6,7 @@ |
| 6 | * | 6 | * |
| 7 | * @module OrchestrationReactor | 7 | * @module OrchestrationReactor |
| 8 | */ | 8 | */ |
| 9 | import { ServiceMap } from "effect"; | 9 | import { Context } from "effect"; |
| 10 | import type { Effect, Scope } from "effect"; | 10 | import type { Effect, Scope } from "effect"; |
| 11 | 11 | ||
| 12 | /** | 12 | /** |
| ... | @@ -25,7 +25,7 @@ export interface OrchestrationReactorShape { | ... | @@ -25,7 +25,7 @@ export interface OrchestrationReactorShape { |
| 25 | /** | 25 | /** |
| 26 | * OrchestrationReactor - Service tag for orchestration reactor coordination. | 26 | * OrchestrationReactor - Service tag for orchestration reactor coordination. |
| 27 | */ | 27 | */ |
| 28 | export class OrchestrationReactor extends ServiceMap.Service< | 28 | export class OrchestrationReactor extends Context.Service< |
| 29 | OrchestrationReactor, | 29 | OrchestrationReactor, |
| 30 | OrchestrationReactorShape | 30 | OrchestrationReactorShape |
| 31 | >()("t3/orchestration/Services/OrchestrationReactor") {} | 31 | >()("t3/orchestration/Services/OrchestrationReactor") {} |
apps/server/src/orchestration/Services/ProjectionPipeline.ts+2-2| ... | @@ -7,7 +7,7 @@ | ... | @@ -7,7 +7,7 @@ |
| 7 | * @module OrchestrationProjectionPipeline | 7 | * @module OrchestrationProjectionPipeline |
| 8 | */ | 8 | */ |
| 9 | import type { OrchestrationEvent } from "@t3tools/contracts"; | 9 | import type { OrchestrationEvent } from "@t3tools/contracts"; |
| 10 | import { ServiceMap } from "effect"; | 10 | import { Context } from "effect"; |
| 11 | import type { Effect } from "effect"; | 11 | import type { Effect } from "effect"; |
| 12 | 12 | ||
| 13 | import type { ProjectionRepositoryError } from "../../persistence/Errors.ts"; | 13 | import type { ProjectionRepositoryError } from "../../persistence/Errors.ts"; |
| ... | @@ -36,7 +36,7 @@ export interface OrchestrationProjectionPipelineShape { | ... | @@ -36,7 +36,7 @@ export interface OrchestrationProjectionPipelineShape { |
| 36 | /** | 36 | /** |
| 37 | * OrchestrationProjectionPipeline - Service tag for orchestration projections. | 37 | * OrchestrationProjectionPipeline - Service tag for orchestration projections. |
| 38 | */ | 38 | */ |
| 39 | export class OrchestrationProjectionPipeline extends ServiceMap.Service< | 39 | export class OrchestrationProjectionPipeline extends Context.Service< |
| 40 | OrchestrationProjectionPipeline, | 40 | OrchestrationProjectionPipeline, |
| 41 | OrchestrationProjectionPipelineShape | 41 | OrchestrationProjectionPipelineShape |
| 42 | >()("t3/orchestration/Services/ProjectionPipeline/OrchestrationProjectionPipeline") {} | 42 | >()("t3/orchestration/Services/ProjectionPipeline/OrchestrationProjectionPipeline") {} |
apps/server/src/orchestration/Services/ProjectionSnapshotQuery.ts+2-2| ... | @@ -13,7 +13,7 @@ import type { | ... | @@ -13,7 +13,7 @@ import type { |
| 13 | ProjectId, | 13 | ProjectId, |
| 14 | ThreadId, | 14 | ThreadId, |
| 15 | } from "@t3tools/contracts"; | 15 | } from "@t3tools/contracts"; |
| 16 | import { ServiceMap } from "effect"; | 16 | import { Context } from "effect"; |
| 17 | import type { Option } from "effect"; | 17 | import type { Option } from "effect"; |
| 18 | import type { Effect } from "effect"; | 18 | import type { Effect } from "effect"; |
| 19 | 19 | ||
| ... | @@ -74,7 +74,7 @@ export interface ProjectionSnapshotQueryShape { | ... | @@ -74,7 +74,7 @@ export interface ProjectionSnapshotQueryShape { |
| 74 | /** | 74 | /** |
| 75 | * ProjectionSnapshotQuery - Service tag for projection snapshot queries. | 75 | * ProjectionSnapshotQuery - Service tag for projection snapshot queries. |
| 76 | */ | 76 | */ |
| 77 | export class ProjectionSnapshotQuery extends ServiceMap.Service< | 77 | export class ProjectionSnapshotQuery extends Context.Service< |
| 78 | ProjectionSnapshotQuery, | 78 | ProjectionSnapshotQuery, |
| 79 | ProjectionSnapshotQueryShape | 79 | ProjectionSnapshotQueryShape |
| 80 | >()("t3/orchestration/Services/ProjectionSnapshotQuery") {} | 80 | >()("t3/orchestration/Services/ProjectionSnapshotQuery") {} |
apps/server/src/orchestration/Services/ProviderCommandReactor.ts+2-2| ... | @@ -6,7 +6,7 @@ | ... | @@ -6,7 +6,7 @@ |
| 6 | * | 6 | * |
| 7 | * @module ProviderCommandReactor | 7 | * @module ProviderCommandReactor |
| 8 | */ | 8 | */ |
| 9 | import { ServiceMap } from "effect"; | 9 | import { Context } from "effect"; |
| 10 | import type { Effect, Scope } from "effect"; | 10 | import type { Effect, Scope } from "effect"; |
| 11 | 11 | ||
| 12 | /** | 12 | /** |
| ... | @@ -34,7 +34,7 @@ export interface ProviderCommandReactorShape { | ... | @@ -34,7 +34,7 @@ export interface ProviderCommandReactorShape { |
| 34 | /** | 34 | /** |
| 35 | * ProviderCommandReactor - Service tag for provider command reaction workers. | 35 | * ProviderCommandReactor - Service tag for provider command reaction workers. |
| 36 | */ | 36 | */ |
| 37 | export class ProviderCommandReactor extends ServiceMap.Service< | 37 | export class ProviderCommandReactor extends Context.Service< |
| 38 | ProviderCommandReactor, | 38 | ProviderCommandReactor, |
| 39 | ProviderCommandReactorShape | 39 | ProviderCommandReactorShape |
| 40 | >()("t3/orchestration/Services/ProviderCommandReactor") {} | 40 | >()("t3/orchestration/Services/ProviderCommandReactor") {} |
apps/server/src/orchestration/Services/ProviderRuntimeIngestion.ts+2-2| ... | @@ -6,7 +6,7 @@ | ... | @@ -6,7 +6,7 @@ |
| 6 | * | 6 | * |
| 7 | * @module ProviderRuntimeIngestionService | 7 | * @module ProviderRuntimeIngestionService |
| 8 | */ | 8 | */ |
| 9 | import { ServiceMap } from "effect"; | 9 | import { Context } from "effect"; |
| 10 | import type { Effect, Scope } from "effect"; | 10 | import type { Effect, Scope } from "effect"; |
| 11 | 11 | ||
| 12 | /** | 12 | /** |
| ... | @@ -34,7 +34,7 @@ export interface ProviderRuntimeIngestionShape { | ... | @@ -34,7 +34,7 @@ export interface ProviderRuntimeIngestionShape { |
| 34 | /** | 34 | /** |
| 35 | * ProviderRuntimeIngestionService - Service tag for runtime ingestion workers. | 35 | * ProviderRuntimeIngestionService - Service tag for runtime ingestion workers. |
| 36 | */ | 36 | */ |
| 37 | export class ProviderRuntimeIngestionService extends ServiceMap.Service< | 37 | export class ProviderRuntimeIngestionService extends Context.Service< |
| 38 | ProviderRuntimeIngestionService, | 38 | ProviderRuntimeIngestionService, |
| 39 | ProviderRuntimeIngestionShape | 39 | ProviderRuntimeIngestionShape |
| 40 | >()("t3/orchestration/Services/ProviderRuntimeIngestion/ProviderRuntimeIngestionService") {} | 40 | >()("t3/orchestration/Services/ProviderRuntimeIngestion/ProviderRuntimeIngestionService") {} |
apps/server/src/orchestration/Services/RuntimeReceiptBus.ts+4-5| ... | @@ -15,7 +15,7 @@ | ... | @@ -15,7 +15,7 @@ |
| 15 | * @module RuntimeReceiptBus | 15 | * @module RuntimeReceiptBus |
| 16 | */ | 16 | */ |
| 17 | import { CheckpointRef, IsoDateTime, NonNegativeInt, ThreadId, TurnId } from "@t3tools/contracts"; | 17 | import { CheckpointRef, IsoDateTime, NonNegativeInt, ThreadId, TurnId } from "@t3tools/contracts"; |
| 18 | import { Schema, ServiceMap } from "effect"; | 18 | import { Schema, Context } from "effect"; |
| 19 | import type { Effect, Stream } from "effect"; | 19 | import type { Effect, Stream } from "effect"; |
| 20 | 20 | ||
| 21 | export const CheckpointBaselineCapturedReceipt = Schema.Struct({ | 21 | export const CheckpointBaselineCapturedReceipt = Schema.Struct({ |
| ... | @@ -59,7 +59,6 @@ export interface RuntimeReceiptBusShape { | ... | @@ -59,7 +59,6 @@ export interface RuntimeReceiptBusShape { |
| 59 | readonly streamEventsForTest: Stream.Stream<OrchestrationRuntimeReceipt>; | 59 | readonly streamEventsForTest: Stream.Stream<OrchestrationRuntimeReceipt>; |
| 60 | } | 60 | } |
| 61 | 61 | ||
| 62 | export class RuntimeReceiptBus extends ServiceMap.Service< | 62 | export class RuntimeReceiptBus extends Context.Service<RuntimeReceiptBus, RuntimeReceiptBusShape>()( |
| 63 | RuntimeReceiptBus, | 63 | "t3/orchestration/Services/RuntimeReceiptBus", |
| 64 | RuntimeReceiptBusShape | 64 | ) {} |
| 65 | >()("t3/orchestration/Services/RuntimeReceiptBus") {} |
apps/server/src/orchestration/commandInvariants.test.ts+24-26| ... | @@ -25,7 +25,7 @@ const readModel: OrchestrationReadModel = { | ... | @@ -25,7 +25,7 @@ const readModel: OrchestrationReadModel = { |
| 25 | updatedAt: now, | 25 | updatedAt: now, |
| 26 | projects: [ | 26 | projects: [ |
| 27 | { | 27 | { |
| 28 | id: ProjectId.makeUnsafe("project-a"), | 28 | id: ProjectId.make("project-a"), |
| 29 | title: "Project A", | 29 | title: "Project A", |
| 30 | workspaceRoot: "/tmp/project-a", | 30 | workspaceRoot: "/tmp/project-a", |
| 31 | defaultModelSelection: { | 31 | defaultModelSelection: { |
| ... | @@ -38,7 +38,7 @@ const readModel: OrchestrationReadModel = { | ... | @@ -38,7 +38,7 @@ const readModel: OrchestrationReadModel = { |
| 38 | deletedAt: null, | 38 | deletedAt: null, |
| 39 | }, | 39 | }, |
| 40 | { | 40 | { |
| 41 | id: ProjectId.makeUnsafe("project-b"), | 41 | id: ProjectId.make("project-b"), |
| 42 | title: "Project B", | 42 | title: "Project B", |
| 43 | workspaceRoot: "/tmp/project-b", | 43 | workspaceRoot: "/tmp/project-b", |
| 44 | defaultModelSelection: { | 44 | defaultModelSelection: { |
| ... | @@ -53,8 +53,8 @@ const readModel: OrchestrationReadModel = { | ... | @@ -53,8 +53,8 @@ const readModel: OrchestrationReadModel = { |
| 53 | ], | 53 | ], |
| 54 | threads: [ | 54 | threads: [ |
| 55 | { | 55 | { |
| 56 | id: ThreadId.makeUnsafe("thread-1"), | 56 | id: ThreadId.make("thread-1"), |
| 57 | projectId: ProjectId.makeUnsafe("project-a"), | 57 | projectId: ProjectId.make("project-a"), |
| 58 | title: "Thread A", | 58 | title: "Thread A", |
| 59 | modelSelection: { | 59 | modelSelection: { |
| 60 | provider: "codex", | 60 | provider: "codex", |
| ... | @@ -76,8 +76,8 @@ const readModel: OrchestrationReadModel = { | ... | @@ -76,8 +76,8 @@ const readModel: OrchestrationReadModel = { |
| 76 | deletedAt: null, | 76 | deletedAt: null, |
| 77 | }, | 77 | }, |
| 78 | { | 78 | { |
| 79 | id: ThreadId.makeUnsafe("thread-2"), | 79 | id: ThreadId.make("thread-2"), |
| 80 | projectId: ProjectId.makeUnsafe("project-b"), | 80 | projectId: ProjectId.make("project-b"), |
| 81 | title: "Thread B", | 81 | title: "Thread B", |
| 82 | modelSelection: { | 82 | modelSelection: { |
| 83 | provider: "codex", | 83 | provider: "codex", |
| ... | @@ -103,10 +103,10 @@ const readModel: OrchestrationReadModel = { | ... | @@ -103,10 +103,10 @@ const readModel: OrchestrationReadModel = { |
| 103 | 103 | ||
| 104 | const messageSendCommand: OrchestrationCommand = { | 104 | const messageSendCommand: OrchestrationCommand = { |
| 105 | type: "thread.turn.start", | 105 | type: "thread.turn.start", |
| 106 | commandId: CommandId.makeUnsafe("cmd-1"), | 106 | commandId: CommandId.make("cmd-1"), |
| 107 | threadId: ThreadId.makeUnsafe("thread-1"), | 107 | threadId: ThreadId.make("thread-1"), |
| 108 | message: { | 108 | message: { |
| 109 | messageId: MessageId.makeUnsafe("msg-1"), | 109 | messageId: MessageId.make("msg-1"), |
| 110 | role: "user", | 110 | role: "user", |
| 111 | text: "hello", | 111 | text: "hello", |
| 112 | attachments: [], | 112 | attachments: [], |
| ... | @@ -118,13 +118,11 @@ const messageSendCommand: OrchestrationCommand = { | ... | @@ -118,13 +118,11 @@ const messageSendCommand: OrchestrationCommand = { |
| 118 | 118 | ||
| 119 | describe("commandInvariants", () => { | 119 | describe("commandInvariants", () => { |
| 120 | it("finds threads by id and project", () => { | 120 | it("finds threads by id and project", () => { |
| 121 | expect(findThreadById(readModel, ThreadId.makeUnsafe("thread-1"))?.projectId).toBe("project-a"); | 121 | expect(findThreadById(readModel, ThreadId.make("thread-1"))?.projectId).toBe("project-a"); |
| 122 | expect(findThreadById(readModel, ThreadId.makeUnsafe("missing"))).toBeUndefined(); | 122 | expect(findThreadById(readModel, ThreadId.make("missing"))).toBeUndefined(); |
| 123 | expect( | 123 | expect( |
| 124 | listThreadsByProjectId(readModel, ProjectId.makeUnsafe("project-b")).map( | 124 | listThreadsByProjectId(readModel, ProjectId.make("project-b")).map((thread) => thread.id), |
| 125 | (thread) => thread.id, | 125 | ).toEqual([ThreadId.make("thread-2")]); |
| 126 | ), | ||
| 127 | ).toEqual([ThreadId.makeUnsafe("thread-2")]); | ||
| 128 | }); | 126 | }); |
| 129 | 127 | ||
| 130 | it("requires existing thread", async () => { | 128 | it("requires existing thread", async () => { |
| ... | @@ -132,17 +130,17 @@ describe("commandInvariants", () => { | ... | @@ -132,17 +130,17 @@ describe("commandInvariants", () => { |
| 132 | requireThread({ | 130 | requireThread({ |
| 133 | readModel, | 131 | readModel, |
| 134 | command: messageSendCommand, | 132 | command: messageSendCommand, |
| 135 | threadId: ThreadId.makeUnsafe("thread-1"), | 133 | threadId: ThreadId.make("thread-1"), |
| 136 | }), | 134 | }), |
| 137 | ); | 135 | ); |
| 138 | expect(thread.id).toBe(ThreadId.makeUnsafe("thread-1")); | 136 | expect(thread.id).toBe(ThreadId.make("thread-1")); |
| 139 | 137 | ||
| 140 | await expect( | 138 | await expect( |
| 141 | Effect.runPromise( | 139 | Effect.runPromise( |
| 142 | requireThread({ | 140 | requireThread({ |
| 143 | readModel, | 141 | readModel, |
| 144 | command: messageSendCommand, | 142 | command: messageSendCommand, |
| 145 | threadId: ThreadId.makeUnsafe("missing"), | 143 | threadId: ThreadId.make("missing"), |
| 146 | }), | 144 | }), |
| 147 | ), | 145 | ), |
| 148 | ).rejects.toThrow("does not exist"); | 146 | ).rejects.toThrow("does not exist"); |
| ... | @@ -154,9 +152,9 @@ describe("commandInvariants", () => { | ... | @@ -154,9 +152,9 @@ describe("commandInvariants", () => { |
| 154 | readModel, | 152 | readModel, |
| 155 | command: { | 153 | command: { |
| 156 | type: "thread.create", | 154 | type: "thread.create", |
| 157 | commandId: CommandId.makeUnsafe("cmd-2"), | 155 | commandId: CommandId.make("cmd-2"), |
| 158 | threadId: ThreadId.makeUnsafe("thread-3"), | 156 | threadId: ThreadId.make("thread-3"), |
| 159 | projectId: ProjectId.makeUnsafe("project-a"), | 157 | projectId: ProjectId.make("project-a"), |
| 160 | title: "new", | 158 | title: "new", |
| 161 | modelSelection: { | 159 | modelSelection: { |
| 162 | provider: "codex", | 160 | provider: "codex", |
| ... | @@ -168,7 +166,7 @@ describe("commandInvariants", () => { | ... | @@ -168,7 +166,7 @@ describe("commandInvariants", () => { |
| 168 | worktreePath: null, | 166 | worktreePath: null, |
| 169 | createdAt: now, | 167 | createdAt: now, |
| 170 | }, | 168 | }, |
| 171 | threadId: ThreadId.makeUnsafe("thread-3"), | 169 | threadId: ThreadId.make("thread-3"), |
| 172 | }), | 170 | }), |
| 173 | ); | 171 | ); |
| 174 | 172 | ||
| ... | @@ -178,9 +176,9 @@ describe("commandInvariants", () => { | ... | @@ -178,9 +176,9 @@ describe("commandInvariants", () => { |
| 178 | readModel, | 176 | readModel, |
| 179 | command: { | 177 | command: { |
| 180 | type: "thread.create", | 178 | type: "thread.create", |
| 181 | commandId: CommandId.makeUnsafe("cmd-3"), | 179 | commandId: CommandId.make("cmd-3"), |
| 182 | threadId: ThreadId.makeUnsafe("thread-1"), | 180 | threadId: ThreadId.make("thread-1"), |
| 183 | projectId: ProjectId.makeUnsafe("project-a"), | 181 | projectId: ProjectId.make("project-a"), |
| 184 | title: "dup", | 182 | title: "dup", |
| 185 | modelSelection: { | 183 | modelSelection: { |
| 186 | provider: "codex", | 184 | provider: "codex", |
| ... | @@ -192,7 +190,7 @@ describe("commandInvariants", () => { | ... | @@ -192,7 +190,7 @@ describe("commandInvariants", () => { |
| 192 | worktreePath: null, | 190 | worktreePath: null, |
| 193 | createdAt: now, | 191 | createdAt: now, |
| 194 | }, | 192 | }, |
| 195 | threadId: ThreadId.makeUnsafe("thread-1"), | 193 | threadId: ThreadId.make("thread-1"), |
| 196 | }), | 194 | }), |
| 197 | ), | 195 | ), |
| 198 | ).rejects.toThrow("already exists"); | 196 | ).rejects.toThrow("already exists"); |
apps/server/src/orchestration/decider.projectScripts.test.ts+34-34| ... | @@ -12,9 +12,9 @@ import { Effect } from "effect"; | ... | @@ -12,9 +12,9 @@ import { Effect } from "effect"; |
| 12 | import { decideOrchestrationCommand } from "./decider.ts"; | 12 | import { decideOrchestrationCommand } from "./decider.ts"; |
| 13 | import { createEmptyReadModel, projectEvent } from "./projector.ts"; | 13 | import { createEmptyReadModel, projectEvent } from "./projector.ts"; |
| 14 | 14 | ||
| 15 | const asEventId = (value: string): EventId => EventId.makeUnsafe(value); | 15 | const asEventId = (value: string): EventId => EventId.make(value); |
| 16 | const asProjectId = (value: string): ProjectId => ProjectId.makeUnsafe(value); | 16 | const asProjectId = (value: string): ProjectId => ProjectId.make(value); |
| 17 | const asMessageId = (value: string): MessageId => MessageId.makeUnsafe(value); | 17 | const asMessageId = (value: string): MessageId => MessageId.make(value); |
| 18 | 18 | ||
| 19 | describe("decider project scripts", () => { | 19 | describe("decider project scripts", () => { |
| 20 | it("emits empty scripts on project.create", async () => { | 20 | it("emits empty scripts on project.create", async () => { |
| ... | @@ -25,7 +25,7 @@ describe("decider project scripts", () => { | ... | @@ -25,7 +25,7 @@ describe("decider project scripts", () => { |
| 25 | decideOrchestrationCommand({ | 25 | decideOrchestrationCommand({ |
| 26 | command: { | 26 | command: { |
| 27 | type: "project.create", | 27 | type: "project.create", |
| 28 | commandId: CommandId.makeUnsafe("cmd-project-create-scripts"), | 28 | commandId: CommandId.make("cmd-project-create-scripts"), |
| 29 | projectId: asProjectId("project-scripts"), | 29 | projectId: asProjectId("project-scripts"), |
| 30 | title: "Scripts", | 30 | title: "Scripts", |
| 31 | workspaceRoot: "/tmp/scripts", | 31 | workspaceRoot: "/tmp/scripts", |
| ... | @@ -51,9 +51,9 @@ describe("decider project scripts", () => { | ... | @@ -51,9 +51,9 @@ describe("decider project scripts", () => { |
| 51 | aggregateId: asProjectId("project-scripts"), | 51 | aggregateId: asProjectId("project-scripts"), |
| 52 | type: "project.created", | 52 | type: "project.created", |
| 53 | occurredAt: now, | 53 | occurredAt: now, |
| 54 | commandId: CommandId.makeUnsafe("cmd-project-create-scripts"), | 54 | commandId: CommandId.make("cmd-project-create-scripts"), |
| 55 | causationEventId: null, | 55 | causationEventId: null, |
| 56 | correlationId: CommandId.makeUnsafe("cmd-project-create-scripts"), | 56 | correlationId: CommandId.make("cmd-project-create-scripts"), |
| 57 | metadata: {}, | 57 | metadata: {}, |
| 58 | payload: { | 58 | payload: { |
| 59 | projectId: asProjectId("project-scripts"), | 59 | projectId: asProjectId("project-scripts"), |
| ... | @@ -81,7 +81,7 @@ describe("decider project scripts", () => { | ... | @@ -81,7 +81,7 @@ describe("decider project scripts", () => { |
| 81 | decideOrchestrationCommand({ | 81 | decideOrchestrationCommand({ |
| 82 | command: { | 82 | command: { |
| 83 | type: "project.meta.update", | 83 | type: "project.meta.update", |
| 84 | commandId: CommandId.makeUnsafe("cmd-project-update-scripts"), | 84 | commandId: CommandId.make("cmd-project-update-scripts"), |
| 85 | projectId: asProjectId("project-scripts"), | 85 | projectId: asProjectId("project-scripts"), |
| 86 | scripts: Array.from(scripts), | 86 | scripts: Array.from(scripts), |
| 87 | }, | 87 | }, |
| ... | @@ -105,9 +105,9 @@ describe("decider project scripts", () => { | ... | @@ -105,9 +105,9 @@ describe("decider project scripts", () => { |
| 105 | aggregateId: asProjectId("project-1"), | 105 | aggregateId: asProjectId("project-1"), |
| 106 | type: "project.created", | 106 | type: "project.created", |
| 107 | occurredAt: now, | 107 | occurredAt: now, |
| 108 | commandId: CommandId.makeUnsafe("cmd-project-create"), | 108 | commandId: CommandId.make("cmd-project-create"), |
| 109 | causationEventId: null, | 109 | causationEventId: null, |
| 110 | correlationId: CommandId.makeUnsafe("cmd-project-create"), | 110 | correlationId: CommandId.make("cmd-project-create"), |
| 111 | metadata: {}, | 111 | metadata: {}, |
| 112 | payload: { | 112 | payload: { |
| 113 | projectId: asProjectId("project-1"), | 113 | projectId: asProjectId("project-1"), |
| ... | @@ -125,15 +125,15 @@ describe("decider project scripts", () => { | ... | @@ -125,15 +125,15 @@ describe("decider project scripts", () => { |
| 125 | sequence: 2, | 125 | sequence: 2, |
| 126 | eventId: asEventId("evt-thread-create"), | 126 | eventId: asEventId("evt-thread-create"), |
| 127 | aggregateKind: "thread", | 127 | aggregateKind: "thread", |
| 128 | aggregateId: ThreadId.makeUnsafe("thread-1"), | 128 | aggregateId: ThreadId.make("thread-1"), |
| 129 | type: "thread.created", | 129 | type: "thread.created", |
| 130 | occurredAt: now, | 130 | occurredAt: now, |
| 131 | commandId: CommandId.makeUnsafe("cmd-thread-create"), | 131 | commandId: CommandId.make("cmd-thread-create"), |
| 132 | causationEventId: null, | 132 | causationEventId: null, |
| 133 | correlationId: CommandId.makeUnsafe("cmd-thread-create"), | 133 | correlationId: CommandId.make("cmd-thread-create"), |
| 134 | metadata: {}, | 134 | metadata: {}, |
| 135 | payload: { | 135 | payload: { |
| 136 | threadId: ThreadId.makeUnsafe("thread-1"), | 136 | threadId: ThreadId.make("thread-1"), |
| 137 | projectId: asProjectId("project-1"), | 137 | projectId: asProjectId("project-1"), |
| 138 | title: "Thread", | 138 | title: "Thread", |
| 139 | modelSelection: { | 139 | modelSelection: { |
| ... | @@ -154,8 +154,8 @@ describe("decider project scripts", () => { | ... | @@ -154,8 +154,8 @@ describe("decider project scripts", () => { |
| 154 | decideOrchestrationCommand({ | 154 | decideOrchestrationCommand({ |
| 155 | command: { | 155 | command: { |
| 156 | type: "thread.turn.start", | 156 | type: "thread.turn.start", |
| 157 | commandId: CommandId.makeUnsafe("cmd-turn-start"), | 157 | commandId: CommandId.make("cmd-turn-start"), |
| 158 | threadId: ThreadId.makeUnsafe("thread-1"), | 158 | threadId: ThreadId.make("thread-1"), |
| 159 | message: { | 159 | message: { |
| 160 | messageId: asMessageId("message-user-1"), | 160 | messageId: asMessageId("message-user-1"), |
| 161 | role: "user", | 161 | role: "user", |
| ... | @@ -189,7 +189,7 @@ describe("decider project scripts", () => { | ... | @@ -189,7 +189,7 @@ describe("decider project scripts", () => { |
| 189 | return; | 189 | return; |
| 190 | } | 190 | } |
| 191 | expect(turnStartEvent.payload).toMatchObject({ | 191 | expect(turnStartEvent.payload).toMatchObject({ |
| 192 | threadId: ThreadId.makeUnsafe("thread-1"), | 192 | threadId: ThreadId.make("thread-1"), |
| 193 | messageId: asMessageId("message-user-1"), | 193 | messageId: asMessageId("message-user-1"), |
| 194 | modelSelection: { | 194 | modelSelection: { |
| 195 | provider: "codex", | 195 | provider: "codex", |
| ... | @@ -214,9 +214,9 @@ describe("decider project scripts", () => { | ... | @@ -214,9 +214,9 @@ describe("decider project scripts", () => { |
| 214 | aggregateId: asProjectId("project-1"), | 214 | aggregateId: asProjectId("project-1"), |
| 215 | type: "project.created", | 215 | type: "project.created", |
| 216 | occurredAt: now, | 216 | occurredAt: now, |
| 217 | commandId: CommandId.makeUnsafe("cmd-project-create"), | 217 | commandId: CommandId.make("cmd-project-create"), |
| 218 | causationEventId: null, | 218 | causationEventId: null, |
| 219 | correlationId: CommandId.makeUnsafe("cmd-project-create"), | 219 | correlationId: CommandId.make("cmd-project-create"), |
| 220 | metadata: {}, | 220 | metadata: {}, |
| 221 | payload: { | 221 | payload: { |
| 222 | projectId: asProjectId("project-1"), | 222 | projectId: asProjectId("project-1"), |
| ... | @@ -234,15 +234,15 @@ describe("decider project scripts", () => { | ... | @@ -234,15 +234,15 @@ describe("decider project scripts", () => { |
| 234 | sequence: 2, | 234 | sequence: 2, |
| 235 | eventId: asEventId("evt-thread-create"), | 235 | eventId: asEventId("evt-thread-create"), |
| 236 | aggregateKind: "thread", | 236 | aggregateKind: "thread", |
| 237 | aggregateId: ThreadId.makeUnsafe("thread-1"), | 237 | aggregateId: ThreadId.make("thread-1"), |
| 238 | type: "thread.created", | 238 | type: "thread.created", |
| 239 | occurredAt: now, | 239 | occurredAt: now, |
| 240 | commandId: CommandId.makeUnsafe("cmd-thread-create"), | 240 | commandId: CommandId.make("cmd-thread-create"), |
| 241 | causationEventId: null, | 241 | causationEventId: null, |
| 242 | correlationId: CommandId.makeUnsafe("cmd-thread-create"), | 242 | correlationId: CommandId.make("cmd-thread-create"), |
| 243 | metadata: {}, | 243 | metadata: {}, |
| 244 | payload: { | 244 | payload: { |
| 245 | threadId: ThreadId.makeUnsafe("thread-1"), | 245 | threadId: ThreadId.make("thread-1"), |
| 246 | projectId: asProjectId("project-1"), | 246 | projectId: asProjectId("project-1"), |
| 247 | title: "Thread", | 247 | title: "Thread", |
| 248 | modelSelection: { | 248 | modelSelection: { |
| ... | @@ -263,8 +263,8 @@ describe("decider project scripts", () => { | ... | @@ -263,8 +263,8 @@ describe("decider project scripts", () => { |
| 263 | decideOrchestrationCommand({ | 263 | decideOrchestrationCommand({ |
| 264 | command: { | 264 | command: { |
| 265 | type: "thread.runtime-mode.set", | 265 | type: "thread.runtime-mode.set", |
| 266 | commandId: CommandId.makeUnsafe("cmd-runtime-mode-set"), | 266 | commandId: CommandId.make("cmd-runtime-mode-set"), |
| 267 | threadId: ThreadId.makeUnsafe("thread-1"), | 267 | threadId: ThreadId.make("thread-1"), |
| 268 | runtimeMode: "approval-required", | 268 | runtimeMode: "approval-required", |
| 269 | createdAt: now, | 269 | createdAt: now, |
| 270 | }, | 270 | }, |
| ... | @@ -279,7 +279,7 @@ describe("decider project scripts", () => { | ... | @@ -279,7 +279,7 @@ describe("decider project scripts", () => { |
| 279 | expect(singleResult).toMatchObject({ | 279 | expect(singleResult).toMatchObject({ |
| 280 | type: "thread.runtime-mode-set", | 280 | type: "thread.runtime-mode-set", |
| 281 | payload: { | 281 | payload: { |
| 282 | threadId: ThreadId.makeUnsafe("thread-1"), | 282 | threadId: ThreadId.make("thread-1"), |
| 283 | runtimeMode: "approval-required", | 283 | runtimeMode: "approval-required", |
| 284 | }, | 284 | }, |
| 285 | }); | 285 | }); |
| ... | @@ -296,9 +296,9 @@ describe("decider project scripts", () => { | ... | @@ -296,9 +296,9 @@ describe("decider project scripts", () => { |
| 296 | aggregateId: asProjectId("project-1"), | 296 | aggregateId: asProjectId("project-1"), |
| 297 | type: "project.created", | 297 | type: "project.created", |
| 298 | occurredAt: now, | 298 | occurredAt: now, |
| 299 | commandId: CommandId.makeUnsafe("cmd-project-create"), | 299 | commandId: CommandId.make("cmd-project-create"), |
| 300 | causationEventId: null, | 300 | causationEventId: null, |
| 301 | correlationId: CommandId.makeUnsafe("cmd-project-create"), | 301 | correlationId: CommandId.make("cmd-project-create"), |
| 302 | metadata: {}, | 302 | metadata: {}, |
| 303 | payload: { | 303 | payload: { |
| 304 | projectId: asProjectId("project-1"), | 304 | projectId: asProjectId("project-1"), |
| ... | @@ -316,15 +316,15 @@ describe("decider project scripts", () => { | ... | @@ -316,15 +316,15 @@ describe("decider project scripts", () => { |
| 316 | sequence: 2, | 316 | sequence: 2, |
| 317 | eventId: asEventId("evt-thread-create"), | 317 | eventId: asEventId("evt-thread-create"), |
| 318 | aggregateKind: "thread", | 318 | aggregateKind: "thread", |
| 319 | aggregateId: ThreadId.makeUnsafe("thread-1"), | 319 | aggregateId: ThreadId.make("thread-1"), |
| 320 | type: "thread.created", | 320 | type: "thread.created", |
| 321 | occurredAt: now, | 321 | occurredAt: now, |
| 322 | commandId: CommandId.makeUnsafe("cmd-thread-create"), | 322 | commandId: CommandId.make("cmd-thread-create"), |
| 323 | causationEventId: null, | 323 | causationEventId: null, |
| 324 | correlationId: CommandId.makeUnsafe("cmd-thread-create"), | 324 | correlationId: CommandId.make("cmd-thread-create"), |
| 325 | metadata: {}, | 325 | metadata: {}, |
| 326 | payload: { | 326 | payload: { |
| 327 | threadId: ThreadId.makeUnsafe("thread-1"), | 327 | threadId: ThreadId.make("thread-1"), |
| 328 | projectId: asProjectId("project-1"), | 328 | projectId: asProjectId("project-1"), |
| 329 | title: "Thread", | 329 | title: "Thread", |
| 330 | modelSelection: { | 330 | modelSelection: { |
| ... | @@ -345,8 +345,8 @@ describe("decider project scripts", () => { | ... | @@ -345,8 +345,8 @@ describe("decider project scripts", () => { |
| 345 | decideOrchestrationCommand({ | 345 | decideOrchestrationCommand({ |
| 346 | command: { | 346 | command: { |
| 347 | type: "thread.interaction-mode.set", | 347 | type: "thread.interaction-mode.set", |
| 348 | commandId: CommandId.makeUnsafe("cmd-interaction-mode-set"), | 348 | commandId: CommandId.make("cmd-interaction-mode-set"), |
| 349 | threadId: ThreadId.makeUnsafe("thread-1"), | 349 | threadId: ThreadId.make("thread-1"), |
| 350 | interactionMode: "plan", | 350 | interactionMode: "plan", |
| 351 | createdAt: now, | 351 | createdAt: now, |
| 352 | }, | 352 | }, |
| ... | @@ -361,7 +361,7 @@ describe("decider project scripts", () => { | ... | @@ -361,7 +361,7 @@ describe("decider project scripts", () => { |
| 361 | expect(singleResult).toMatchObject({ | 361 | expect(singleResult).toMatchObject({ |
| 362 | type: "thread.interaction-mode-set", | 362 | type: "thread.interaction-mode-set", |
| 363 | payload: { | 363 | payload: { |
| 364 | threadId: ThreadId.makeUnsafe("thread-1"), | 364 | threadId: ThreadId.make("thread-1"), |
| 365 | interactionMode: "plan", | 365 | interactionMode: "plan", |
| 366 | }, | 366 | }, |
| 367 | }); | 367 | }); |
apps/server/src/orchestration/projector.test.ts+4-4| ... | @@ -21,15 +21,15 @@ function makeEvent(input: { | ... | @@ -21,15 +21,15 @@ function makeEvent(input: { |
| 21 | }): OrchestrationEvent { | 21 | }): OrchestrationEvent { |
| 22 | return { | 22 | return { |
| 23 | sequence: input.sequence, | 23 | sequence: input.sequence, |
| 24 | eventId: EventId.makeUnsafe(`event-${input.sequence}`), | 24 | eventId: EventId.make(`event-${input.sequence}`), |
| 25 | type: input.type, | 25 | type: input.type, |
| 26 | aggregateKind: input.aggregateKind, | 26 | aggregateKind: input.aggregateKind, |
| 27 | aggregateId: | 27 | aggregateId: |
| 28 | input.aggregateKind === "project" | 28 | input.aggregateKind === "project" |
| 29 | ? ProjectId.makeUnsafe(input.aggregateId) | 29 | ? ProjectId.make(input.aggregateId) |
| 30 | : ThreadId.makeUnsafe(input.aggregateId), | 30 | : ThreadId.make(input.aggregateId), |
| 31 | occurredAt: input.occurredAt, | 31 | occurredAt: input.occurredAt, |
| 32 | commandId: input.commandId === null ? null : CommandId.makeUnsafe(input.commandId), | 32 | commandId: input.commandId === null ? null : CommandId.make(input.commandId), |
| 33 | causationEventId: null, | 33 | causationEventId: null, |
| 34 | correlationId: null, | 34 | correlationId: null, |
| 35 | metadata: {}, | 35 | metadata: {}, |
apps/server/src/persistence/Layers/OrchestrationEventStore.test.ts+8-8| ... | @@ -21,18 +21,18 @@ layer("OrchestrationEventStore", (it) => { | ... | @@ -21,18 +21,18 @@ layer("OrchestrationEventStore", (it) => { |
| 21 | 21 | ||
| 22 | const appended = yield* eventStore.append({ | 22 | const appended = yield* eventStore.append({ |
| 23 | type: "project.created", | 23 | type: "project.created", |
| 24 | eventId: EventId.makeUnsafe("evt-store-roundtrip"), | 24 | eventId: EventId.make("evt-store-roundtrip"), |
| 25 | aggregateKind: "project", | 25 | aggregateKind: "project", |
| 26 | aggregateId: ProjectId.makeUnsafe("project-roundtrip"), | 26 | aggregateId: ProjectId.make("project-roundtrip"), |
| 27 | occurredAt: now, | 27 | occurredAt: now, |
| 28 | commandId: CommandId.makeUnsafe("cmd-store-roundtrip"), | 28 | commandId: CommandId.make("cmd-store-roundtrip"), |
| 29 | causationEventId: null, | 29 | causationEventId: null, |
| 30 | correlationId: CommandId.makeUnsafe("cmd-store-roundtrip"), | 30 | correlationId: CommandId.make("cmd-store-roundtrip"), |
| 31 | metadata: { | 31 | metadata: { |
| 32 | adapterKey: "codex", | 32 | adapterKey: "codex", |
| 33 | }, | 33 | }, |
| 34 | payload: { | 34 | payload: { |
| 35 | projectId: ProjectId.makeUnsafe("project-roundtrip"), | 35 | projectId: ProjectId.make("project-roundtrip"), |
| 36 | title: "Roundtrip Project", | 36 | title: "Roundtrip Project", |
| 37 | workspaceRoot: "/tmp/project-roundtrip", | 37 | workspaceRoot: "/tmp/project-roundtrip", |
| 38 | defaultModelSelection: null, | 38 | defaultModelSelection: null, |
| ... | @@ -87,13 +87,13 @@ layer("OrchestrationEventStore", (it) => { | ... | @@ -87,13 +87,13 @@ layer("OrchestrationEventStore", (it) => { |
| 87 | metadata_json | 87 | metadata_json |
| 88 | ) | 88 | ) |
| 89 | VALUES ( | 89 | VALUES ( |
| 90 | ${EventId.makeUnsafe("evt-store-invalid-json")}, | 90 | ${EventId.make("evt-store-invalid-json")}, |
| 91 | ${"project"}, | 91 | ${"project"}, |
| 92 | ${ProjectId.makeUnsafe("project-invalid-json")}, | 92 | ${ProjectId.make("project-invalid-json")}, |
| 93 | ${0}, | 93 | ${0}, |
| 94 | ${"project.created"}, | 94 | ${"project.created"}, |
| 95 | ${now}, | 95 | ${now}, |
| 96 | ${CommandId.makeUnsafe("cmd-store-invalid-json")}, | 96 | ${CommandId.make("cmd-store-invalid-json")}, |
| 97 | ${null}, | 97 | ${null}, |
| 98 | ${null}, | 98 | ${null}, |
| 99 | ${"server"}, | 99 | ${"server"}, |
apps/server/src/persistence/Layers/ProjectionRepositories.test.ts+5-5| ... | @@ -24,7 +24,7 @@ projectionRepositoriesLayer("Projection repositories", (it) => { | ... | @@ -24,7 +24,7 @@ projectionRepositoriesLayer("Projection repositories", (it) => { |
| 24 | const sql = yield* SqlClient.SqlClient; | 24 | const sql = yield* SqlClient.SqlClient; |
| 25 | 25 | ||
| 26 | yield* projects.upsert({ | 26 | yield* projects.upsert({ |
| 27 | projectId: ProjectId.makeUnsafe("project-null-options"), | 27 | projectId: ProjectId.make("project-null-options"), |
| 28 | title: "Null options project", | 28 | title: "Null options project", |
| 29 | workspaceRoot: "/tmp/project-null-options", | 29 | workspaceRoot: "/tmp/project-null-options", |
| 30 | defaultModelSelection: { | 30 | defaultModelSelection: { |
| ... | @@ -58,7 +58,7 @@ projectionRepositoriesLayer("Projection repositories", (it) => { | ... | @@ -58,7 +58,7 @@ projectionRepositoriesLayer("Projection repositories", (it) => { |
| 58 | ); | 58 | ); |
| 59 | 59 | ||
| 60 | const persisted = yield* projects.getById({ | 60 | const persisted = yield* projects.getById({ |
| 61 | projectId: ProjectId.makeUnsafe("project-null-options"), | 61 | projectId: ProjectId.make("project-null-options"), |
| 62 | }); | 62 | }); |
| 63 | assert.deepStrictEqual(Option.getOrNull(persisted)?.defaultModelSelection, { | 63 | assert.deepStrictEqual(Option.getOrNull(persisted)?.defaultModelSelection, { |
| 64 | provider: "codex", | 64 | provider: "codex", |
| ... | @@ -73,8 +73,8 @@ projectionRepositoriesLayer("Projection repositories", (it) => { | ... | @@ -73,8 +73,8 @@ projectionRepositoriesLayer("Projection repositories", (it) => { |
| 73 | const sql = yield* SqlClient.SqlClient; | 73 | const sql = yield* SqlClient.SqlClient; |
| 74 | 74 | ||
| 75 | yield* threads.upsert({ | 75 | yield* threads.upsert({ |
| 76 | threadId: ThreadId.makeUnsafe("thread-null-options"), | 76 | threadId: ThreadId.make("thread-null-options"), |
| 77 | projectId: ProjectId.makeUnsafe("project-null-options"), | 77 | projectId: ProjectId.make("project-null-options"), |
| 78 | title: "Null options thread", | 78 | title: "Null options thread", |
| 79 | modelSelection: { | 79 | modelSelection: { |
| 80 | provider: "claudeAgent", | 80 | provider: "claudeAgent", |
| ... | @@ -112,7 +112,7 @@ projectionRepositoriesLayer("Projection repositories", (it) => { | ... | @@ -112,7 +112,7 @@ projectionRepositoriesLayer("Projection repositories", (it) => { |
| 112 | ); | 112 | ); |
| 113 | 113 | ||
| 114 | const persisted = yield* threads.getById({ | 114 | const persisted = yield* threads.getById({ |
| 115 | threadId: ThreadId.makeUnsafe("thread-null-options"), | 115 | threadId: ThreadId.make("thread-null-options"), |
| 116 | }); | 116 | }); |
| 117 | assert.deepStrictEqual(Option.getOrNull(persisted)?.modelSelection, { | 117 | assert.deepStrictEqual(Option.getOrNull(persisted)?.modelSelection, { |
| 118 | provider: "claudeAgent", | 118 | provider: "claudeAgent", |
apps/server/src/persistence/Layers/ProjectionThreadMessages.test.ts+4-4| ... | @@ -14,8 +14,8 @@ layer("ProjectionThreadMessageRepository", (it) => { | ... | @@ -14,8 +14,8 @@ layer("ProjectionThreadMessageRepository", (it) => { |
| 14 | it.effect("preserves existing attachments when upsert omits attachments", () => | 14 | it.effect("preserves existing attachments when upsert omits attachments", () => |
| 15 | Effect.gen(function* () { | 15 | Effect.gen(function* () { |
| 16 | const repository = yield* ProjectionThreadMessageRepository; | 16 | const repository = yield* ProjectionThreadMessageRepository; |
| 17 | const threadId = ThreadId.makeUnsafe("thread-preserve-attachments"); | 17 | const threadId = ThreadId.make("thread-preserve-attachments"); |
| 18 | const messageId = MessageId.makeUnsafe("message-preserve-attachments"); | 18 | const messageId = MessageId.make("message-preserve-attachments"); |
| 19 | const createdAt = "2026-02-28T19:00:00.000Z"; | 19 | const createdAt = "2026-02-28T19:00:00.000Z"; |
| 20 | const updatedAt = "2026-02-28T19:00:01.000Z"; | 20 | const updatedAt = "2026-02-28T19:00:01.000Z"; |
| 21 | const persistedAttachments = [ | 21 | const persistedAttachments = [ |
| ... | @@ -68,8 +68,8 @@ layer("ProjectionThreadMessageRepository", (it) => { | ... | @@ -68,8 +68,8 @@ layer("ProjectionThreadMessageRepository", (it) => { |
| 68 | it.effect("allows explicit attachment clearing with an empty array", () => | 68 | it.effect("allows explicit attachment clearing with an empty array", () => |
| 69 | Effect.gen(function* () { | 69 | Effect.gen(function* () { |
| 70 | const repository = yield* ProjectionThreadMessageRepository; | 70 | const repository = yield* ProjectionThreadMessageRepository; |
| 71 | const threadId = ThreadId.makeUnsafe("thread-clear-attachments"); | 71 | const threadId = ThreadId.make("thread-clear-attachments"); |
| 72 | const messageId = MessageId.makeUnsafe("message-clear-attachments"); | 72 | const messageId = MessageId.make("message-clear-attachments"); |
| 73 | const createdAt = "2026-02-28T19:10:00.000Z"; | 73 | const createdAt = "2026-02-28T19:10:00.000Z"; |
| 74 | 74 | ||
| 75 | yield* repository.upsert({ | 75 | yield* repository.upsert({ |
apps/server/src/persistence/NodeSqliteClient.ts+10-10| ... | @@ -15,7 +15,7 @@ import { identity } from "effect/Function"; | ... | @@ -15,7 +15,7 @@ import { identity } from "effect/Function"; |
| 15 | import * as Layer from "effect/Layer"; | 15 | import * as Layer from "effect/Layer"; |
| 16 | import * as Scope from "effect/Scope"; | 16 | import * as Scope from "effect/Scope"; |
| 17 | import * as Semaphore from "effect/Semaphore"; | 17 | import * as Semaphore from "effect/Semaphore"; |
| 18 | import * as ServiceMap from "effect/ServiceMap"; | 18 | import * as Context from "effect/Context"; |
| 19 | import * as Stream from "effect/Stream"; | 19 | import * as Stream from "effect/Stream"; |
| 20 | import * as Reactivity from "effect/unstable/reactivity/Reactivity"; | 20 | import * as Reactivity from "effect/unstable/reactivity/Reactivity"; |
| 21 | import * as Client from "effect/unstable/sql/SqlClient"; | 21 | import * as Client from "effect/unstable/sql/SqlClient"; |
| ... | @@ -32,7 +32,7 @@ export type TypeId = "~local/sqlite-node/SqliteClient"; | ... | @@ -32,7 +32,7 @@ export type TypeId = "~local/sqlite-node/SqliteClient"; |
| 32 | /** | 32 | /** |
| 33 | * SqliteClient - Effect service tag for the sqlite SQL client. | 33 | * SqliteClient - Effect service tag for the sqlite SQL client. |
| 34 | */ | 34 | */ |
| 35 | export const SqliteClient = ServiceMap.Service<Client.SqlClient>("t3/persistence/NodeSqliteClient"); | 35 | export const SqliteClient = Context.Service<Client.SqlClient>("t3/persistence/NodeSqliteClient"); |
| 36 | 36 | ||
| 37 | export interface SqliteClientConfig { | 37 | export interface SqliteClientConfig { |
| 38 | readonly filename: string; | 38 | readonly filename: string; |
| ... | @@ -120,7 +120,7 @@ const makeWithDatabase = Effect.fn("makeWithDatabase")(function* ( | ... | @@ -120,7 +120,7 @@ const makeWithDatabase = Effect.fn("makeWithDatabase")(function* ( |
| 120 | 120 | ||
| 121 | const runStatement = (statement: StatementSync, params: ReadonlyArray<unknown>, raw: boolean) => | 121 | const runStatement = (statement: StatementSync, params: ReadonlyArray<unknown>, raw: boolean) => |
| 122 | Effect.withFiber<ReadonlyArray<any>, SqlError>((fiber) => { | 122 | Effect.withFiber<ReadonlyArray<any>, SqlError>((fiber) => { |
| 123 | statement.setReadBigInts(Boolean(ServiceMap.get(fiber.services, Client.SafeIntegers))); | 123 | statement.setReadBigInts(Boolean(Context.get(fiber.context, Client.SafeIntegers))); |
| 124 | try { | 124 | try { |
| 125 | if (hasRows(statement)) { | 125 | if (hasRows(statement)) { |
| 126 | return Effect.succeed(statement.all(...(params as any))); | 126 | return Effect.succeed(statement.all(...(params as any))); |
| ... | @@ -200,7 +200,7 @@ const makeWithDatabase = Effect.fn("makeWithDatabase")(function* ( | ... | @@ -200,7 +200,7 @@ const makeWithDatabase = Effect.fn("makeWithDatabase")(function* ( |
| 200 | const acquirer = semaphore.withPermits(1)(Effect.succeed(connection)); | 200 | const acquirer = semaphore.withPermits(1)(Effect.succeed(connection)); |
| 201 | const transactionAcquirer = Effect.uninterruptibleMask((restore) => { | 201 | const transactionAcquirer = Effect.uninterruptibleMask((restore) => { |
| 202 | const fiber = Fiber.getCurrent()!; | 202 | const fiber = Fiber.getCurrent()!; |
| 203 | const scope = ServiceMap.getUnsafe(fiber.services, Scope.Scope); | 203 | const scope = Context.getUnsafe(fiber.context, Scope.Scope); |
| 204 | return Effect.as( | 204 | return Effect.as( |
| 205 | Effect.tap(restore(semaphore.take(1)), () => Scope.addFinalizer(scope, semaphore.release(1))), | 205 | Effect.tap(restore(semaphore.take(1)), () => Scope.addFinalizer(scope, semaphore.release(1))), |
| 206 | connection, | 206 | connection, |
| ... | @@ -251,27 +251,27 @@ const makeMemory = ( | ... | @@ -251,27 +251,27 @@ const makeMemory = ( |
| 251 | export const layerConfig = ( | 251 | export const layerConfig = ( |
| 252 | config: Config.Wrap<SqliteClientConfig>, | 252 | config: Config.Wrap<SqliteClientConfig>, |
| 253 | ): Layer.Layer<Client.SqlClient, Config.ConfigError> => | 253 | ): Layer.Layer<Client.SqlClient, Config.ConfigError> => |
| 254 | Layer.effectServices( | 254 | Layer.effectContext( |
| 255 | Config.unwrap(config) | 255 | Config.unwrap(config) |
| 256 | .asEffect() | 256 | .asEffect() |
| 257 | .pipe( | 257 | .pipe( |
| 258 | Effect.flatMap(make), | 258 | Effect.flatMap(make), |
| 259 | Effect.map((client) => | 259 | Effect.map((client) => |
| 260 | ServiceMap.make(SqliteClient, client).pipe(ServiceMap.add(Client.SqlClient, client)), | 260 | Context.make(SqliteClient, client).pipe(Context.add(Client.SqlClient, client)), |
| 261 | ), | 261 | ), |
| 262 | ), | 262 | ), |
| 263 | ).pipe(Layer.provide(Reactivity.layer)); | 263 | ).pipe(Layer.provide(Reactivity.layer)); |
| 264 | 264 | ||
| 265 | export const layer = (config: SqliteClientConfig): Layer.Layer<Client.SqlClient> => | 265 | export const layer = (config: SqliteClientConfig): Layer.Layer<Client.SqlClient> => |
| 266 | Layer.effectServices( | 266 | Layer.effectContext( |
| 267 | Effect.map(make(config), (client) => | 267 | Effect.map(make(config), (client) => |
| 268 | ServiceMap.make(SqliteClient, client).pipe(ServiceMap.add(Client.SqlClient, client)), | 268 | Context.make(SqliteClient, client).pipe(Context.add(Client.SqlClient, client)), |
| 269 | ), | 269 | ), |
| 270 | ).pipe(Layer.provide(Reactivity.layer)); | 270 | ).pipe(Layer.provide(Reactivity.layer)); |
| 271 | 271 | ||
| 272 | export const layerMemory = (config: SqliteMemoryClientConfig = {}): Layer.Layer<Client.SqlClient> => | 272 | export const layerMemory = (config: SqliteMemoryClientConfig = {}): Layer.Layer<Client.SqlClient> => |
| 273 | Layer.effectServices( | 273 | Layer.effectContext( |
| 274 | Effect.map(makeMemory(config), (client) => | 274 | Effect.map(makeMemory(config), (client) => |
| 275 | ServiceMap.make(SqliteClient, client).pipe(ServiceMap.add(Client.SqlClient, client)), | 275 | Context.make(SqliteClient, client).pipe(Context.add(Client.SqlClient, client)), |
| 276 | ), | 276 | ), |
| 277 | ).pipe(Layer.provide(Reactivity.layer)); | 277 | ).pipe(Layer.provide(Reactivity.layer)); |
apps/server/src/persistence/Services/AuthPairingLinks.ts+2-2| ... | @@ -1,4 +1,4 @@ | ... | @@ -1,4 +1,4 @@ |
| 1 | import { Option, Schema, ServiceMap } from "effect"; | 1 | import { Option, Schema, Context } from "effect"; |
| 2 | import type { Effect } from "effect"; | 2 | import type { Effect } from "effect"; |
| 3 | 3 | ||
| 4 | import type { AuthPairingLinkRepositoryError } from "../Errors.ts"; | 4 | import type { AuthPairingLinkRepositoryError } from "../Errors.ts"; |
| ... | @@ -70,7 +70,7 @@ export interface AuthPairingLinkRepositoryShape { | ... | @@ -70,7 +70,7 @@ export interface AuthPairingLinkRepositoryShape { |
| 70 | ) => Effect.Effect<Option.Option<AuthPairingLinkRecord>, AuthPairingLinkRepositoryError>; | 70 | ) => Effect.Effect<Option.Option<AuthPairingLinkRecord>, AuthPairingLinkRepositoryError>; |
| 71 | } | 71 | } |
| 72 | 72 | ||
| 73 | export class AuthPairingLinkRepository extends ServiceMap.Service< | 73 | export class AuthPairingLinkRepository extends Context.Service< |
| 74 | AuthPairingLinkRepository, | 74 | AuthPairingLinkRepository, |
| 75 | AuthPairingLinkRepositoryShape | 75 | AuthPairingLinkRepositoryShape |
| 76 | >()("t3/persistence/Services/AuthPairingLinks/AuthPairingLinkRepository") {} | 76 | >()("t3/persistence/Services/AuthPairingLinks/AuthPairingLinkRepository") {} |
apps/server/src/persistence/Services/AuthSessions.ts+2-2| ... | @@ -1,5 +1,5 @@ | ... | @@ -1,5 +1,5 @@ |
| 1 | import { AuthClientMetadataDeviceType, AuthSessionId } from "@t3tools/contracts"; | 1 | import { AuthClientMetadataDeviceType, AuthSessionId } from "@t3tools/contracts"; |
| 2 | import { Option, Schema, ServiceMap } from "effect"; | 2 | import { Option, Schema, Context } from "effect"; |
| 3 | import type { Effect } from "effect"; | 3 | import type { Effect } from "effect"; |
| 4 | 4 | ||
| 5 | import type { AuthSessionRepositoryError } from "../Errors.ts"; | 5 | import type { AuthSessionRepositoryError } from "../Errors.ts"; |
| ... | @@ -87,7 +87,7 @@ export interface AuthSessionRepositoryShape { | ... | @@ -87,7 +87,7 @@ export interface AuthSessionRepositoryShape { |
| 87 | ) => Effect.Effect<void, AuthSessionRepositoryError>; | 87 | ) => Effect.Effect<void, AuthSessionRepositoryError>; |
| 88 | } | 88 | } |
| 89 | 89 | ||
| 90 | export class AuthSessionRepository extends ServiceMap.Service< | 90 | export class AuthSessionRepository extends Context.Service< |
| 91 | AuthSessionRepository, | 91 | AuthSessionRepository, |
| 92 | AuthSessionRepositoryShape | 92 | AuthSessionRepositoryShape |
| 93 | >()("t3/persistence/Services/AuthSessions/AuthSessionRepository") {} | 93 | >()("t3/persistence/Services/AuthSessions/AuthSessionRepository") {} |
apps/server/src/persistence/Services/OrchestrationCommandReceipts.ts+2-2| ... | @@ -15,7 +15,7 @@ import { | ... | @@ -15,7 +15,7 @@ import { |
| 15 | ProjectId, | 15 | ProjectId, |
| 16 | ThreadId, | 16 | ThreadId, |
| 17 | } from "@t3tools/contracts"; | 17 | } from "@t3tools/contracts"; |
| 18 | import { Option, Schema, ServiceMap } from "effect"; | 18 | import { Option, Schema, Context } from "effect"; |
| 19 | import type { Effect } from "effect"; | 19 | import type { Effect } from "effect"; |
| 20 | 20 | ||
| 21 | import type { OrchestrationCommandReceiptRepositoryError } from "../Errors.ts"; | 21 | import type { OrchestrationCommandReceiptRepositoryError } from "../Errors.ts"; |
| ... | @@ -63,7 +63,7 @@ export interface OrchestrationCommandReceiptRepositoryShape { | ... | @@ -63,7 +63,7 @@ export interface OrchestrationCommandReceiptRepositoryShape { |
| 63 | /** | 63 | /** |
| 64 | * OrchestrationCommandReceiptRepository - Service tag for command receipt persistence. | 64 | * OrchestrationCommandReceiptRepository - Service tag for command receipt persistence. |
| 65 | */ | 65 | */ |
| 66 | export class OrchestrationCommandReceiptRepository extends ServiceMap.Service< | 66 | export class OrchestrationCommandReceiptRepository extends Context.Service< |
| 67 | OrchestrationCommandReceiptRepository, | 67 | OrchestrationCommandReceiptRepository, |
| 68 | OrchestrationCommandReceiptRepositoryShape | 68 | OrchestrationCommandReceiptRepositoryShape |
| 69 | >()("t3/persistence/Services/OrchestrationCommandReceipts/OrchestrationCommandReceiptRepository") {} | 69 | >()("t3/persistence/Services/OrchestrationCommandReceipts/OrchestrationCommandReceiptRepository") {} |
apps/server/src/persistence/Services/OrchestrationEventStore.ts+3-3| ... | @@ -4,13 +4,13 @@ | ... | @@ -4,13 +4,13 @@ |
| 4 | * Owns durable append/replay access to the orchestration event stream. It does | 4 | * Owns durable append/replay access to the orchestration event stream. It does |
| 5 | * not reduce events into read models or apply command validation rules. | 5 | * not reduce events into read models or apply command validation rules. |
| 6 | * | 6 | * |
| 7 | * Uses Effect `ServiceMap.Service` for dependency injection and exposes typed | 7 | * Uses Effect `Context.Service` for dependency injection and exposes typed |
| 8 | * persistence/decode errors for event append and replay operations. | 8 | * persistence/decode errors for event append and replay operations. |
| 9 | * | 9 | * |
| 10 | * @module OrchestrationEventStore | 10 | * @module OrchestrationEventStore |
| 11 | */ | 11 | */ |
| 12 | import { OrchestrationEvent } from "@t3tools/contracts"; | 12 | import { OrchestrationEvent } from "@t3tools/contracts"; |
| 13 | import { ServiceMap } from "effect"; | 13 | import { Context } from "effect"; |
| 14 | import type { Effect, Stream } from "effect"; | 14 | import type { Effect, Stream } from "effect"; |
| 15 | 15 | ||
| 16 | import type { OrchestrationEventStoreError } from "../Errors.ts"; | 16 | import type { OrchestrationEventStoreError } from "../Errors.ts"; |
| ... | @@ -64,7 +64,7 @@ export interface OrchestrationEventStoreShape { | ... | @@ -64,7 +64,7 @@ export interface OrchestrationEventStoreShape { |
| 64 | * }) | 64 | * }) |
| 65 | * ``` | 65 | * ``` |
| 66 | */ | 66 | */ |
| 67 | export class OrchestrationEventStore extends ServiceMap.Service< | 67 | export class OrchestrationEventStore extends Context.Service< |
| 68 | OrchestrationEventStore, | 68 | OrchestrationEventStore, |
| 69 | OrchestrationEventStoreShape | 69 | OrchestrationEventStoreShape |
| 70 | >()("t3/persistence/Services/OrchestrationEventStore") {} | 70 | >()("t3/persistence/Services/OrchestrationEventStore") {} |
apps/server/src/persistence/Services/ProjectionCheckpoints.ts+2-2| ... | @@ -16,7 +16,7 @@ import { | ... | @@ -16,7 +16,7 @@ import { |
| 16 | ThreadId, | 16 | ThreadId, |
| 17 | TurnId, | 17 | TurnId, |
| 18 | } from "@t3tools/contracts"; | 18 | } from "@t3tools/contracts"; |
| 19 | import { Option, ServiceMap, Schema } from "effect"; | 19 | import { Option, Context, Schema } from "effect"; |
| 20 | import type { Effect } from "effect"; | 20 | import type { Effect } from "effect"; |
| 21 | 21 | ||
| 22 | import type { ProjectionRepositoryError } from "../Errors.ts"; | 22 | import type { ProjectionRepositoryError } from "../Errors.ts"; |
| ... | @@ -87,7 +87,7 @@ export interface ProjectionCheckpointRepositoryShape { | ... | @@ -87,7 +87,7 @@ export interface ProjectionCheckpointRepositoryShape { |
| 87 | /** | 87 | /** |
| 88 | * ProjectionCheckpointRepository - Service tag for checkpoint projection persistence. | 88 | * ProjectionCheckpointRepository - Service tag for checkpoint projection persistence. |
| 89 | */ | 89 | */ |
| 90 | export class ProjectionCheckpointRepository extends ServiceMap.Service< | 90 | export class ProjectionCheckpointRepository extends Context.Service< |
| 91 | ProjectionCheckpointRepository, | 91 | ProjectionCheckpointRepository, |
| 92 | ProjectionCheckpointRepositoryShape | 92 | ProjectionCheckpointRepositoryShape |
| 93 | >()("t3/persistence/Services/ProjectionCheckpoints/ProjectionCheckpointRepository") {} | 93 | >()("t3/persistence/Services/ProjectionCheckpoints/ProjectionCheckpointRepository") {} |
apps/server/src/persistence/Services/ProjectionPendingApprovals.ts+2-2| ... | @@ -14,7 +14,7 @@ import { | ... | @@ -14,7 +14,7 @@ import { |
| 14 | ThreadId, | 14 | ThreadId, |
| 15 | TurnId, | 15 | TurnId, |
| 16 | } from "@t3tools/contracts"; | 16 | } from "@t3tools/contracts"; |
| 17 | import { Option, Schema, ServiceMap } from "effect"; | 17 | import { Option, Schema, Context } from "effect"; |
| 18 | import type { Effect } from "effect"; | 18 | import type { Effect } from "effect"; |
| 19 | 19 | ||
| 20 | import type { ProjectionRepositoryError } from "../Errors.ts"; | 20 | import type { ProjectionRepositoryError } from "../Errors.ts"; |
| ... | @@ -85,7 +85,7 @@ export interface ProjectionPendingApprovalRepositoryShape { | ... | @@ -85,7 +85,7 @@ export interface ProjectionPendingApprovalRepositoryShape { |
| 85 | /** | 85 | /** |
| 86 | * ProjectionPendingApprovalRepository - Service tag for pending approval persistence. | 86 | * ProjectionPendingApprovalRepository - Service tag for pending approval persistence. |
| 87 | */ | 87 | */ |
| 88 | export class ProjectionPendingApprovalRepository extends ServiceMap.Service< | 88 | export class ProjectionPendingApprovalRepository extends Context.Service< |
| 89 | ProjectionPendingApprovalRepository, | 89 | ProjectionPendingApprovalRepository, |
| 90 | ProjectionPendingApprovalRepositoryShape | 90 | ProjectionPendingApprovalRepositoryShape |
| 91 | >()("t3/persistence/Services/ProjectionPendingApprovals/ProjectionPendingApprovalRepository") {} | 91 | >()("t3/persistence/Services/ProjectionPendingApprovals/ProjectionPendingApprovalRepository") {} |
apps/server/src/persistence/Services/ProjectionProjects.ts+2-2| ... | @@ -7,7 +7,7 @@ | ... | @@ -7,7 +7,7 @@ |
| 7 | * @module ProjectionProjectRepository | 7 | * @module ProjectionProjectRepository |
| 8 | */ | 8 | */ |
| 9 | import { IsoDateTime, ModelSelection, ProjectId, ProjectScript } from "@t3tools/contracts"; | 9 | import { IsoDateTime, ModelSelection, ProjectId, ProjectScript } from "@t3tools/contracts"; |
| 10 | import { Option, Schema, ServiceMap } from "effect"; | 10 | import { Option, Schema, Context } from "effect"; |
| 11 | import type { Effect } from "effect"; | 11 | import type { Effect } from "effect"; |
| 12 | 12 | ||
| 13 | import type { ProjectionRepositoryError } from "../Errors.ts"; | 13 | import type { ProjectionRepositoryError } from "../Errors.ts"; |
| ... | @@ -73,7 +73,7 @@ export interface ProjectionProjectRepositoryShape { | ... | @@ -73,7 +73,7 @@ export interface ProjectionProjectRepositoryShape { |
| 73 | /** | 73 | /** |
| 74 | * ProjectionProjectRepository - Service tag for project projection persistence. | 74 | * ProjectionProjectRepository - Service tag for project projection persistence. |
| 75 | */ | 75 | */ |
| 76 | export class ProjectionProjectRepository extends ServiceMap.Service< | 76 | export class ProjectionProjectRepository extends Context.Service< |
| 77 | ProjectionProjectRepository, | 77 | ProjectionProjectRepository, |
| 78 | ProjectionProjectRepositoryShape | 78 | ProjectionProjectRepositoryShape |
| 79 | >()("t3/persistence/Services/ProjectionProjects/ProjectionProjectRepository") {} | 79 | >()("t3/persistence/Services/ProjectionProjects/ProjectionProjectRepository") {} |
apps/server/src/persistence/Services/ProjectionState.ts+2-2| ... | @@ -7,7 +7,7 @@ | ... | @@ -7,7 +7,7 @@ |
| 7 | * @module ProjectionStateRepository | 7 | * @module ProjectionStateRepository |
| 8 | */ | 8 | */ |
| 9 | import { IsoDateTime, NonNegativeInt } from "@t3tools/contracts"; | 9 | import { IsoDateTime, NonNegativeInt } from "@t3tools/contracts"; |
| 10 | import { Option, Schema, ServiceMap } from "effect"; | 10 | import { Option, Schema, Context } from "effect"; |
| 11 | import type { Effect } from "effect"; | 11 | import type { Effect } from "effect"; |
| 12 | 12 | ||
| 13 | import type { ProjectionRepositoryError } from "../Errors.ts"; | 13 | import type { ProjectionRepositoryError } from "../Errors.ts"; |
| ... | @@ -58,7 +58,7 @@ export interface ProjectionStateRepositoryShape { | ... | @@ -58,7 +58,7 @@ export interface ProjectionStateRepositoryShape { |
| 58 | /** | 58 | /** |
| 59 | * ProjectionStateRepository - Service tag for projection cursor persistence. | 59 | * ProjectionStateRepository - Service tag for projection cursor persistence. |
| 60 | */ | 60 | */ |
| 61 | export class ProjectionStateRepository extends ServiceMap.Service< | 61 | export class ProjectionStateRepository extends Context.Service< |
| 62 | ProjectionStateRepository, | 62 | ProjectionStateRepository, |
| 63 | ProjectionStateRepositoryShape | 63 | ProjectionStateRepositoryShape |
| 64 | >()("t3/persistence/Services/ProjectionState/ProjectionStateRepository") {} | 64 | >()("t3/persistence/Services/ProjectionState/ProjectionStateRepository") {} |
apps/server/src/persistence/Services/ProjectionThreadActivities.ts+2-2| ... | @@ -14,7 +14,7 @@ import { | ... | @@ -14,7 +14,7 @@ import { |
| 14 | ThreadId, | 14 | ThreadId, |
| 15 | TurnId, | 15 | TurnId, |
| 16 | } from "@t3tools/contracts"; | 16 | } from "@t3tools/contracts"; |
| 17 | import { Schema, ServiceMap } from "effect"; | 17 | import { Schema, Context } from "effect"; |
| 18 | import type { Effect } from "effect"; | 18 | import type { Effect } from "effect"; |
| 19 | 19 | ||
| 20 | import type { ProjectionRepositoryError } from "../Errors.ts"; | 20 | import type { ProjectionRepositoryError } from "../Errors.ts"; |
| ... | @@ -77,7 +77,7 @@ export interface ProjectionThreadActivityRepositoryShape { | ... | @@ -77,7 +77,7 @@ export interface ProjectionThreadActivityRepositoryShape { |
| 77 | /** | 77 | /** |
| 78 | * ProjectionThreadActivityRepository - Service tag for thread activity persistence. | 78 | * ProjectionThreadActivityRepository - Service tag for thread activity persistence. |
| 79 | */ | 79 | */ |
| 80 | export class ProjectionThreadActivityRepository extends ServiceMap.Service< | 80 | export class ProjectionThreadActivityRepository extends Context.Service< |
| 81 | ProjectionThreadActivityRepository, | 81 | ProjectionThreadActivityRepository, |
| 82 | ProjectionThreadActivityRepositoryShape | 82 | ProjectionThreadActivityRepositoryShape |
| 83 | >()("t3/persistence/Services/ProjectionThreadActivities/ProjectionThreadActivityRepository") {} | 83 | >()("t3/persistence/Services/ProjectionThreadActivities/ProjectionThreadActivityRepository") {} |
apps/server/src/persistence/Services/ProjectionThreadMessages.ts+2-2| ... | @@ -14,7 +14,7 @@ import { | ... | @@ -14,7 +14,7 @@ import { |
| 14 | TurnId, | 14 | TurnId, |
| 15 | IsoDateTime, | 15 | IsoDateTime, |
| 16 | } from "@t3tools/contracts"; | 16 | } from "@t3tools/contracts"; |
| 17 | import { Schema, ServiceMap } from "effect"; | 17 | import { Schema, Context } from "effect"; |
| 18 | import type { Option } from "effect"; | 18 | import type { Option } from "effect"; |
| 19 | import type { Effect } from "effect"; | 19 | import type { Effect } from "effect"; |
| 20 | 20 | ||
| ... | @@ -88,7 +88,7 @@ export interface ProjectionThreadMessageRepositoryShape { | ... | @@ -88,7 +88,7 @@ export interface ProjectionThreadMessageRepositoryShape { |
| 88 | /** | 88 | /** |
| 89 | * ProjectionThreadMessageRepository - Service tag for message projection persistence. | 89 | * ProjectionThreadMessageRepository - Service tag for message projection persistence. |
| 90 | */ | 90 | */ |
| 91 | export class ProjectionThreadMessageRepository extends ServiceMap.Service< | 91 | export class ProjectionThreadMessageRepository extends Context.Service< |
| 92 | ProjectionThreadMessageRepository, | 92 | ProjectionThreadMessageRepository, |
| 93 | ProjectionThreadMessageRepositoryShape | 93 | ProjectionThreadMessageRepositoryShape |
| 94 | >()("t3/persistence/Services/ProjectionThreadMessages/ProjectionThreadMessageRepository") {} | 94 | >()("t3/persistence/Services/ProjectionThreadMessages/ProjectionThreadMessageRepository") {} |
apps/server/src/persistence/Services/ProjectionThreadProposedPlans.ts+2-2| ... | @@ -5,7 +5,7 @@ import { | ... | @@ -5,7 +5,7 @@ import { |
| 5 | TrimmedNonEmptyString, | 5 | TrimmedNonEmptyString, |
| 6 | TurnId, | 6 | TurnId, |
| 7 | } from "@t3tools/contracts"; | 7 | } from "@t3tools/contracts"; |
| 8 | import { Schema, ServiceMap } from "effect"; | 8 | import { Schema, Context } from "effect"; |
| 9 | import type { Effect } from "effect"; | 9 | import type { Effect } from "effect"; |
| 10 | 10 | ||
| 11 | import type { ProjectionRepositoryError } from "../Errors.ts"; | 11 | import type { ProjectionRepositoryError } from "../Errors.ts"; |
| ... | @@ -46,7 +46,7 @@ export interface ProjectionThreadProposedPlanRepositoryShape { | ... | @@ -46,7 +46,7 @@ export interface ProjectionThreadProposedPlanRepositoryShape { |
| 46 | ) => Effect.Effect<void, ProjectionRepositoryError>; | 46 | ) => Effect.Effect<void, ProjectionRepositoryError>; |
| 47 | } | 47 | } |
| 48 | 48 | ||
| 49 | export class ProjectionThreadProposedPlanRepository extends ServiceMap.Service< | 49 | export class ProjectionThreadProposedPlanRepository extends Context.Service< |
| 50 | ProjectionThreadProposedPlanRepository, | 50 | ProjectionThreadProposedPlanRepository, |
| 51 | ProjectionThreadProposedPlanRepositoryShape | 51 | ProjectionThreadProposedPlanRepositoryShape |
| 52 | >()( | 52 | >()( |
apps/server/src/persistence/Services/ProjectionThreadSessions.ts+2-2| ... | @@ -13,7 +13,7 @@ import { | ... | @@ -13,7 +13,7 @@ import { |
| 13 | ThreadId, | 13 | ThreadId, |
| 14 | TurnId, | 14 | TurnId, |
| 15 | } from "@t3tools/contracts"; | 15 | } from "@t3tools/contracts"; |
| 16 | import { Option, Schema, ServiceMap } from "effect"; | 16 | import { Option, Schema, Context } from "effect"; |
| 17 | import type { Effect } from "effect"; | 17 | import type { Effect } from "effect"; |
| 18 | 18 | ||
| 19 | import type { ProjectionRepositoryError } from "../Errors.ts"; | 19 | import type { ProjectionRepositoryError } from "../Errors.ts"; |
| ... | @@ -68,7 +68,7 @@ export interface ProjectionThreadSessionRepositoryShape { | ... | @@ -68,7 +68,7 @@ export interface ProjectionThreadSessionRepositoryShape { |
| 68 | /** | 68 | /** |
| 69 | * ProjectionThreadSessionRepository - Service tag for thread-session persistence. | 69 | * ProjectionThreadSessionRepository - Service tag for thread-session persistence. |
| 70 | */ | 70 | */ |
| 71 | export class ProjectionThreadSessionRepository extends ServiceMap.Service< | 71 | export class ProjectionThreadSessionRepository extends Context.Service< |
| 72 | ProjectionThreadSessionRepository, | 72 | ProjectionThreadSessionRepository, |
| 73 | ProjectionThreadSessionRepositoryShape | 73 | ProjectionThreadSessionRepositoryShape |
| 74 | >()("t3/persistence/Services/ProjectionThreadSessions/ProjectionThreadSessionRepository") {} | 74 | >()("t3/persistence/Services/ProjectionThreadSessions/ProjectionThreadSessionRepository") {} |
apps/server/src/persistence/Services/ProjectionThreads.ts+2-2| ... | @@ -15,7 +15,7 @@ import { | ... | @@ -15,7 +15,7 @@ import { |
| 15 | ThreadId, | 15 | ThreadId, |
| 16 | TurnId, | 16 | TurnId, |
| 17 | } from "@t3tools/contracts"; | 17 | } from "@t3tools/contracts"; |
| 18 | import { Option, Schema, ServiceMap } from "effect"; | 18 | import { Option, Schema, Context } from "effect"; |
| 19 | import type { Effect } from "effect"; | 19 | import type { Effect } from "effect"; |
| 20 | 20 | ||
| 21 | import type { ProjectionRepositoryError } from "../Errors.ts"; | 21 | import type { ProjectionRepositoryError } from "../Errors.ts"; |
| ... | @@ -90,7 +90,7 @@ export interface ProjectionThreadRepositoryShape { | ... | @@ -90,7 +90,7 @@ export interface ProjectionThreadRepositoryShape { |
| 90 | /** | 90 | /** |
| 91 | * ProjectionThreadRepository - Service tag for thread projection persistence. | 91 | * ProjectionThreadRepository - Service tag for thread projection persistence. |
| 92 | */ | 92 | */ |
| 93 | export class ProjectionThreadRepository extends ServiceMap.Service< | 93 | export class ProjectionThreadRepository extends Context.Service< |
| 94 | ProjectionThreadRepository, | 94 | ProjectionThreadRepository, |
| 95 | ProjectionThreadRepositoryShape | 95 | ProjectionThreadRepositoryShape |
| 96 | >()("t3/persistence/Services/ProjectionThreads/ProjectionThreadRepository") {} | 96 | >()("t3/persistence/Services/ProjectionThreads/ProjectionThreadRepository") {} |
apps/server/src/persistence/Services/ProjectionTurns.ts+2-2| ... | @@ -17,7 +17,7 @@ import { | ... | @@ -17,7 +17,7 @@ import { |
| 17 | ThreadId, | 17 | ThreadId, |
| 18 | TurnId, | 18 | TurnId, |
| 19 | } from "@t3tools/contracts"; | 19 | } from "@t3tools/contracts"; |
| 20 | import { Option, Schema, ServiceMap } from "effect"; | 20 | import { Option, Schema, Context } from "effect"; |
| 21 | import type { Effect } from "effect"; | 21 | import type { Effect } from "effect"; |
| 22 | 22 | ||
| 23 | import type { ProjectionRepositoryError } from "../Errors.ts"; | 23 | import type { ProjectionRepositoryError } from "../Errors.ts"; |
| ... | @@ -162,7 +162,7 @@ export interface ProjectionTurnRepositoryShape { | ... | @@ -162,7 +162,7 @@ export interface ProjectionTurnRepositoryShape { |
| 162 | ) => Effect.Effect<void, ProjectionRepositoryError>; | 162 | ) => Effect.Effect<void, ProjectionRepositoryError>; |
| 163 | } | 163 | } |
| 164 | 164 | ||
| 165 | export class ProjectionTurnRepository extends ServiceMap.Service< | 165 | export class ProjectionTurnRepository extends Context.Service< |
| 166 | ProjectionTurnRepository, | 166 | ProjectionTurnRepository, |
| 167 | ProjectionTurnRepositoryShape | 167 | ProjectionTurnRepositoryShape |
| 168 | >()("t3/persistence/Services/ProjectionTurns/ProjectionTurnRepository") {} | 168 | >()("t3/persistence/Services/ProjectionTurns/ProjectionTurnRepository") {} |
apps/server/src/persistence/Services/ProviderSessionRuntime.ts+2-2| ... | @@ -11,7 +11,7 @@ import { | ... | @@ -11,7 +11,7 @@ import { |
| 11 | RuntimeMode, | 11 | RuntimeMode, |
| 12 | ThreadId, | 12 | ThreadId, |
| 13 | } from "@t3tools/contracts"; | 13 | } from "@t3tools/contracts"; |
| 14 | import { Option, Schema, ServiceMap } from "effect"; | 14 | import { Option, Schema, Context } from "effect"; |
| 15 | import type { Effect } from "effect"; | 15 | import type { Effect } from "effect"; |
| 16 | 16 | ||
| 17 | import type { ProviderSessionRuntimeRepositoryError } from "../Errors.ts"; | 17 | import type { ProviderSessionRuntimeRepositoryError } from "../Errors.ts"; |
| ... | @@ -75,7 +75,7 @@ export interface ProviderSessionRuntimeRepositoryShape { | ... | @@ -75,7 +75,7 @@ export interface ProviderSessionRuntimeRepositoryShape { |
| 75 | /** | 75 | /** |
| 76 | * ProviderSessionRuntimeRepository - Service tag for provider runtime persistence. | 76 | * ProviderSessionRuntimeRepository - Service tag for provider runtime persistence. |
| 77 | */ | 77 | */ |
| 78 | export class ProviderSessionRuntimeRepository extends ServiceMap.Service< | 78 | export class ProviderSessionRuntimeRepository extends Context.Service< |
| 79 | ProviderSessionRuntimeRepository, | 79 | ProviderSessionRuntimeRepository, |
| 80 | ProviderSessionRuntimeRepositoryShape | 80 | ProviderSessionRuntimeRepositoryShape |
| 81 | >()("t3/persistence/Services/ProviderSessionRuntime/ProviderSessionRuntimeRepository") {} | 81 | >()("t3/persistence/Services/ProviderSessionRuntime/ProviderSessionRuntimeRepository") {} |
apps/server/src/project/Layers/RepositoryIdentityResolver.ts+13-11| ... | @@ -116,17 +116,19 @@ async function resolveRepositoryIdentityFromCacheKey( | ... | @@ -116,17 +116,19 @@ async function resolveRepositoryIdentityFromCacheKey( |
| 116 | 116 | ||
| 117 | export const makeRepositoryIdentityResolver = Effect.fn("makeRepositoryIdentityResolver")( | 117 | export const makeRepositoryIdentityResolver = Effect.fn("makeRepositoryIdentityResolver")( |
| 118 | function* (options: RepositoryIdentityResolverOptions = {}) { | 118 | function* (options: RepositoryIdentityResolverOptions = {}) { |
| 119 | const repositoryIdentityCache = yield* Cache.makeWith<string, RepositoryIdentity | null>({ | 119 | const repositoryIdentityCache = yield* Cache.makeWith<string, RepositoryIdentity | null>( |
| 120 | capacity: options.cacheCapacity ?? DEFAULT_REPOSITORY_IDENTITY_CACHE_CAPACITY, | 120 | (cacheKey) => Effect.promise(() => resolveRepositoryIdentityFromCacheKey(cacheKey)), |
| 121 | lookup: (cacheKey) => Effect.promise(() => resolveRepositoryIdentityFromCacheKey(cacheKey)), | 121 | { |
| 122 | timeToLive: Exit.match({ | 122 | capacity: options.cacheCapacity ?? DEFAULT_REPOSITORY_IDENTITY_CACHE_CAPACITY, |
| 123 | onSuccess: (value) => | 123 | timeToLive: Exit.match({ |
| 124 | value === null | 124 | onSuccess: (value) => |
| 125 | ? (options.negativeCacheTtl ?? DEFAULT_NEGATIVE_CACHE_TTL) | 125 | value === null |
| 126 | : (options.positiveCacheTtl ?? DEFAULT_POSITIVE_CACHE_TTL), | 126 | ? (options.negativeCacheTtl ?? DEFAULT_NEGATIVE_CACHE_TTL) |
| 127 | onFailure: () => Duration.zero, | 127 | : (options.positiveCacheTtl ?? DEFAULT_POSITIVE_CACHE_TTL), |
| 128 | }), | 128 | onFailure: () => Duration.zero, |
| 129 | }); | 129 | }), |
| 130 | }, | ||
| 131 | ); | ||
| 130 | 132 | ||
| 131 | const resolve: RepositoryIdentityResolverShape["resolve"] = Effect.fn( | 133 | const resolve: RepositoryIdentityResolverShape["resolve"] = Effect.fn( |
| 132 | "RepositoryIdentityResolver.resolve", | 134 | "RepositoryIdentityResolver.resolve", |
apps/server/src/project/Services/ProjectFaviconResolver.ts+2-2| ... | @@ -6,7 +6,7 @@ | ... | @@ -6,7 +6,7 @@ |
| 6 | * | 6 | * |
| 7 | * @module ProjectFaviconResolver | 7 | * @module ProjectFaviconResolver |
| 8 | */ | 8 | */ |
| 9 | import { ServiceMap } from "effect"; | 9 | import { Context } from "effect"; |
| 10 | import type { Effect } from "effect"; | 10 | import type { Effect } from "effect"; |
| 11 | 11 | ||
| 12 | /** | 12 | /** |
| ... | @@ -24,7 +24,7 @@ export interface ProjectFaviconResolverShape { | ... | @@ -24,7 +24,7 @@ export interface ProjectFaviconResolverShape { |
| 24 | /** | 24 | /** |
| 25 | * ProjectFaviconResolver - Service tag for project favicon resolution. | 25 | * ProjectFaviconResolver - Service tag for project favicon resolution. |
| 26 | */ | 26 | */ |
| 27 | export class ProjectFaviconResolver extends ServiceMap.Service< | 27 | export class ProjectFaviconResolver extends Context.Service< |
| 28 | ProjectFaviconResolver, | 28 | ProjectFaviconResolver, |
| 29 | ProjectFaviconResolverShape | 29 | ProjectFaviconResolverShape |
| 30 | >()("t3/project/Services/ProjectFaviconResolver") {} | 30 | >()("t3/project/Services/ProjectFaviconResolver") {} |
apps/server/src/project/Services/ProjectSetupScriptRunner.ts+2-2| ... | @@ -1,4 +1,4 @@ | ... | @@ -1,4 +1,4 @@ |
| 1 | import { ServiceMap } from "effect"; | 1 | import { Context } from "effect"; |
| 2 | import type { Effect } from "effect"; | 2 | import type { Effect } from "effect"; |
| 3 | 3 | ||
| 4 | export interface ProjectSetupScriptRunnerResultNoScript { | 4 | export interface ProjectSetupScriptRunnerResultNoScript { |
| ... | @@ -31,7 +31,7 @@ export interface ProjectSetupScriptRunnerShape { | ... | @@ -31,7 +31,7 @@ export interface ProjectSetupScriptRunnerShape { |
| 31 | ) => Effect.Effect<ProjectSetupScriptRunnerResult, Error>; | 31 | ) => Effect.Effect<ProjectSetupScriptRunnerResult, Error>; |
| 32 | } | 32 | } |
| 33 | 33 | ||
| 34 | export class ProjectSetupScriptRunner extends ServiceMap.Service< | 34 | export class ProjectSetupScriptRunner extends Context.Service< |
| 35 | ProjectSetupScriptRunner, | 35 | ProjectSetupScriptRunner, |
| 36 | ProjectSetupScriptRunnerShape | 36 | ProjectSetupScriptRunnerShape |
| 37 | >()("t3/project/ProjectSetupScriptRunner") {} | 37 | >()("t3/project/ProjectSetupScriptRunner") {} |
apps/server/src/project/Services/RepositoryIdentityResolver.ts+2-2| ... | @@ -1,12 +1,12 @@ | ... | @@ -1,12 +1,12 @@ |
| 1 | import type { RepositoryIdentity } from "@t3tools/contracts"; | 1 | import type { RepositoryIdentity } from "@t3tools/contracts"; |
| 2 | import { ServiceMap } from "effect"; | 2 | import { Context } from "effect"; |
| 3 | import type { Effect } from "effect"; | 3 | import type { Effect } from "effect"; |
| 4 | 4 | ||
| 5 | export interface RepositoryIdentityResolverShape { | 5 | export interface RepositoryIdentityResolverShape { |
| 6 | readonly resolve: (cwd: string) => Effect.Effect<RepositoryIdentity | null>; | 6 | readonly resolve: (cwd: string) => Effect.Effect<RepositoryIdentity | null>; |
| 7 | } | 7 | } |
| 8 | 8 | ||
| 9 | export class RepositoryIdentityResolver extends ServiceMap.Service< | 9 | export class RepositoryIdentityResolver extends Context.Service< |
| 10 | RepositoryIdentityResolver, | 10 | RepositoryIdentityResolver, |
| 11 | RepositoryIdentityResolverShape | 11 | RepositoryIdentityResolverShape |
| 12 | >()("t3/project/Services/RepositoryIdentityResolver") {} | 12 | >()("t3/project/Services/RepositoryIdentityResolver") {} |
apps/server/src/provider/Layers/ClaudeAdapter.test.ts+21-25| ... | @@ -237,8 +237,8 @@ async function readFirstPromptMessage( | ... | @@ -237,8 +237,8 @@ async function readFirstPromptMessage( |
| 237 | return next.value; | 237 | return next.value; |
| 238 | } | 238 | } |
| 239 | 239 | ||
| 240 | const THREAD_ID = ThreadId.makeUnsafe("thread-claude-1"); | 240 | const THREAD_ID = ThreadId.make("thread-claude-1"); |
| 241 | const RESUME_THREAD_ID = ThreadId.makeUnsafe("thread-claude-resume"); | 241 | const RESUME_THREAD_ID = ThreadId.make("thread-claude-resume"); |
| 242 | 242 | ||
| 243 | describe("ClaudeAdapterLive", () => { | 243 | describe("ClaudeAdapterLive", () => { |
| 244 | it.effect("returns validation error for non-claude provider on startSession", () => { | 244 | it.effect("returns validation error for non-claude provider on startSession", () => { |
| ... | @@ -1104,8 +1104,8 @@ describe("ClaudeAdapterLive", () => { | ... | @@ -1104,8 +1104,8 @@ describe("ClaudeAdapterLive", () => { |
| 1104 | it.effect("closes the session when the Claude stream aborts after a turn starts", () => { | 1104 | it.effect("closes the session when the Claude stream aborts after a turn starts", () => { |
| 1105 | const harness = makeHarness(); | 1105 | const harness = makeHarness(); |
| 1106 | return Effect.gen(function* () { | 1106 | return Effect.gen(function* () { |
| 1107 | const services = yield* Effect.services(); | 1107 | const context = yield* Effect.context<never>(); |
| 1108 | const runFork = Effect.runForkWith(services); | 1108 | const runFork = Effect.runForkWith(context); |
| 1109 | 1109 | ||
| 1110 | const adapter = yield* ClaudeAdapter; | 1110 | const adapter = yield* ClaudeAdapter; |
| 1111 | const runtimeEvents: Array<ProviderRuntimeEvent> = []; | 1111 | const runtimeEvents: Array<ProviderRuntimeEvent> = []; |
| ... | @@ -1204,8 +1204,8 @@ describe("ClaudeAdapterLive", () => { | ... | @@ -1204,8 +1204,8 @@ describe("ClaudeAdapterLive", () => { |
| 1204 | ); | 1204 | ); |
| 1205 | 1205 | ||
| 1206 | return Effect.gen(function* () { | 1206 | return Effect.gen(function* () { |
| 1207 | const services = yield* Effect.services(); | 1207 | const context = yield* Effect.context<never>(); |
| 1208 | const runFork = Effect.runForkWith(services); | 1208 | const runFork = Effect.runForkWith(context); |
| 1209 | 1209 | ||
| 1210 | const adapter = yield* ClaudeAdapter; | 1210 | const adapter = yield* ClaudeAdapter; |
| 1211 | 1211 | ||
| ... | @@ -2108,7 +2108,7 @@ describe("ClaudeAdapterLive", () => { | ... | @@ -2108,7 +2108,7 @@ describe("ClaudeAdapterLive", () => { |
| 2108 | return; | 2108 | return; |
| 2109 | } | 2109 | } |
| 2110 | assert.deepEqual(requested.value.providerRefs, { | 2110 | assert.deepEqual(requested.value.providerRefs, { |
| 2111 | providerItemId: ProviderItemId.makeUnsafe("tool-use-1"), | 2111 | providerItemId: ProviderItemId.make("tool-use-1"), |
| 2112 | }); | 2112 | }); |
| 2113 | const runtimeRequestId = requested.value.requestId; | 2113 | const runtimeRequestId = requested.value.requestId; |
| 2114 | assert.equal(typeof runtimeRequestId, "string"); | 2114 | assert.equal(typeof runtimeRequestId, "string"); |
| ... | @@ -2118,7 +2118,7 @@ describe("ClaudeAdapterLive", () => { | ... | @@ -2118,7 +2118,7 @@ describe("ClaudeAdapterLive", () => { |
| 2118 | 2118 | ||
| 2119 | yield* adapter.respondToRequest( | 2119 | yield* adapter.respondToRequest( |
| 2120 | session.threadId, | 2120 | session.threadId, |
| 2121 | ApprovalRequestId.makeUnsafe(runtimeRequestId), | 2121 | ApprovalRequestId.make(runtimeRequestId), |
| 2122 | "accept", | 2122 | "accept", |
| 2123 | ); | 2123 | ); |
| 2124 | 2124 | ||
| ... | @@ -2134,7 +2134,7 @@ describe("ClaudeAdapterLive", () => { | ... | @@ -2134,7 +2134,7 @@ describe("ClaudeAdapterLive", () => { |
| 2134 | assert.equal(resolved.value.requestId, requested.value.requestId); | 2134 | assert.equal(resolved.value.requestId, requested.value.requestId); |
| 2135 | assert.equal(resolved.value.payload.decision, "accept"); | 2135 | assert.equal(resolved.value.payload.decision, "accept"); |
| 2136 | assert.deepEqual(resolved.value.providerRefs, { | 2136 | assert.deepEqual(resolved.value.providerRefs, { |
| 2137 | providerItemId: ProviderItemId.makeUnsafe("tool-use-1"), | 2137 | providerItemId: ProviderItemId.make("tool-use-1"), |
| 2138 | }); | 2138 | }); |
| 2139 | 2139 | ||
| 2140 | const permissionResult = yield* Effect.promise(() => permissionPromise); | 2140 | const permissionResult = yield* Effect.promise(() => permissionPromise); |
| ... | @@ -2183,7 +2183,7 @@ describe("ClaudeAdapterLive", () => { | ... | @@ -2183,7 +2183,7 @@ describe("ClaudeAdapterLive", () => { |
| 2183 | 2183 | ||
| 2184 | yield* adapter.respondToRequest( | 2184 | yield* adapter.respondToRequest( |
| 2185 | session.threadId, | 2185 | session.threadId, |
| 2186 | ApprovalRequestId.makeUnsafe(String(agentRequested.value.requestId)), | 2186 | ApprovalRequestId.make(String(agentRequested.value.requestId)), |
| 2187 | "accept", | 2187 | "accept", |
| 2188 | ); | 2188 | ); |
| 2189 | yield* Stream.runHead(adapter.streamEvents); | 2189 | yield* Stream.runHead(adapter.streamEvents); |
| ... | @@ -2207,7 +2207,7 @@ describe("ClaudeAdapterLive", () => { | ... | @@ -2207,7 +2207,7 @@ describe("ClaudeAdapterLive", () => { |
| 2207 | 2207 | ||
| 2208 | yield* adapter.respondToRequest( | 2208 | yield* adapter.respondToRequest( |
| 2209 | session.threadId, | 2209 | session.threadId, |
| 2210 | ApprovalRequestId.makeUnsafe(String(grepRequested.value.requestId)), | 2210 | ApprovalRequestId.make(String(grepRequested.value.requestId)), |
| 2211 | "accept", | 2211 | "accept", |
| 2212 | ); | 2212 | ); |
| 2213 | yield* Stream.runHead(adapter.streamEvents); | 2213 | yield* Stream.runHead(adapter.streamEvents); |
| ... | @@ -2629,7 +2629,7 @@ describe("ClaudeAdapterLive", () => { | ... | @@ -2629,7 +2629,7 @@ describe("ClaudeAdapterLive", () => { |
| 2629 | } | 2629 | } |
| 2630 | assert.equal(proposedEvent.value.payload.planMarkdown, "# Ship it\n\n- one\n- two"); | 2630 | assert.equal(proposedEvent.value.payload.planMarkdown, "# Ship it\n\n- one\n- two"); |
| 2631 | assert.deepEqual(proposedEvent.value.providerRefs, { | 2631 | assert.deepEqual(proposedEvent.value.providerRefs, { |
| 2632 | providerItemId: ProviderItemId.makeUnsafe("tool-exit-1"), | 2632 | providerItemId: ProviderItemId.make("tool-exit-1"), |
| 2633 | }); | 2633 | }); |
| 2634 | 2634 | ||
| 2635 | const permissionResult = yield* Effect.promise(() => permissionPromise); | 2635 | const permissionResult = yield* Effect.promise(() => permissionPromise); |
| ... | @@ -2707,7 +2707,7 @@ describe("ClaudeAdapterLive", () => { | ... | @@ -2707,7 +2707,7 @@ describe("ClaudeAdapterLive", () => { |
| 2707 | } | 2707 | } |
| 2708 | assert.equal(proposedEvent.value.payload.planMarkdown, "# Final plan\n\n- capture it"); | 2708 | assert.equal(proposedEvent.value.payload.planMarkdown, "# Final plan\n\n- capture it"); |
| 2709 | assert.deepEqual(proposedEvent.value.providerRefs, { | 2709 | assert.deepEqual(proposedEvent.value.providerRefs, { |
| 2710 | providerItemId: ProviderItemId.makeUnsafe("tool-exit-2"), | 2710 | providerItemId: ProviderItemId.make("tool-exit-2"), |
| 2711 | }); | 2711 | }); |
| 2712 | }).pipe( | 2712 | }).pipe( |
| 2713 | Effect.provideService(Random.Random, makeDeterministicRandomService()), | 2713 | Effect.provideService(Random.Random, makeDeterministicRandomService()), |
| ... | @@ -2798,15 +2798,13 @@ describe("ClaudeAdapterLive", () => { | ... | @@ -2798,15 +2798,13 @@ describe("ClaudeAdapterLive", () => { |
| 2798 | assert.equal(requestedEvent.value.payload.questions.length, 1); | 2798 | assert.equal(requestedEvent.value.payload.questions.length, 1); |
| 2799 | assert.equal(requestedEvent.value.payload.questions[0]?.question, "Which framework?"); | 2799 | assert.equal(requestedEvent.value.payload.questions[0]?.question, "Which framework?"); |
| 2800 | assert.deepEqual(requestedEvent.value.providerRefs, { | 2800 | assert.deepEqual(requestedEvent.value.providerRefs, { |
| 2801 | providerItemId: ProviderItemId.makeUnsafe("tool-ask-1"), | 2801 | providerItemId: ProviderItemId.make("tool-ask-1"), |
| 2802 | }); | 2802 | }); |
| 2803 | 2803 | ||
| 2804 | // Respond with the user's answers. | 2804 | // Respond with the user's answers. |
| 2805 | yield* adapter.respondToUserInput( | 2805 | yield* adapter.respondToUserInput(session.threadId, ApprovalRequestId.make(requestId!), { |
| 2806 | session.threadId, | 2806 | "Which framework?": "React", |
| 2807 | ApprovalRequestId.makeUnsafe(requestId!), | 2807 | }); |
| 2808 | { "Which framework?": "React" }, | ||
| 2809 | ); | ||
| 2810 | 2808 | ||
| 2811 | // The adapter should emit a user-input.resolved event. | 2809 | // The adapter should emit a user-input.resolved event. |
| 2812 | const resolvedEvent = yield* Stream.runHead(adapter.streamEvents); | 2810 | const resolvedEvent = yield* Stream.runHead(adapter.streamEvents); |
| ... | @@ -2822,7 +2820,7 @@ describe("ClaudeAdapterLive", () => { | ... | @@ -2822,7 +2820,7 @@ describe("ClaudeAdapterLive", () => { |
| 2822 | "Which framework?": "React", | 2820 | "Which framework?": "React", |
| 2823 | }); | 2821 | }); |
| 2824 | assert.deepEqual(resolvedEvent.value.providerRefs, { | 2822 | assert.deepEqual(resolvedEvent.value.providerRefs, { |
| 2825 | providerItemId: ProviderItemId.makeUnsafe("tool-ask-1"), | 2823 | providerItemId: ProviderItemId.make("tool-ask-1"), |
| 2826 | }); | 2824 | }); |
| 2827 | 2825 | ||
| 2828 | // The canUseTool promise should resolve with the answers in SDK format. | 2826 | // The canUseTool promise should resolve with the answers in SDK format. |
| ... | @@ -2889,11 +2887,9 @@ describe("ClaudeAdapterLive", () => { | ... | @@ -2889,11 +2887,9 @@ describe("ClaudeAdapterLive", () => { |
| 2889 | } | 2887 | } |
| 2890 | const requestId = requestedEvent.value.requestId; | 2888 | const requestId = requestedEvent.value.requestId; |
| 2891 | 2889 | ||
| 2892 | yield* adapter.respondToUserInput( | 2890 | yield* adapter.respondToUserInput(session.threadId, ApprovalRequestId.make(requestId!), { |
| 2893 | session.threadId, | 2891 | "Deploy to which env?": "Staging", |
| 2894 | ApprovalRequestId.makeUnsafe(requestId!), | 2892 | }); |
| 2895 | { "Deploy to which env?": "Staging" }, | ||
| 2896 | ); | ||
| 2897 | 2893 | ||
| 2898 | // Drain the resolved event. | 2894 | // Drain the resolved event. |
| 2899 | yield* Stream.runHead(adapter.streamEvents); | 2895 | yield* Stream.runHead(adapter.streamEvents); |
apps/server/src/provider/Layers/ClaudeAdapter.ts+16-16| ... | @@ -269,7 +269,7 @@ function isInterruptedResult(result: SDKResultMessage): boolean { | ... | @@ -269,7 +269,7 @@ function isInterruptedResult(result: SDKResultMessage): boolean { |
| 269 | } | 269 | } |
| 270 | 270 | ||
| 271 | function asRuntimeItemId(value: string): RuntimeItemId { | 271 | function asRuntimeItemId(value: string): RuntimeItemId { |
| 272 | return RuntimeItemId.makeUnsafe(value); | 272 | return RuntimeItemId.make(value); |
| 273 | } | 273 | } |
| 274 | 274 | ||
| 275 | function maxClaudeContextWindowFromModelUsage(modelUsage: unknown): number | undefined { | 275 | function maxClaudeContextWindowFromModelUsage(modelUsage: unknown): number | undefined { |
| ... | @@ -353,7 +353,7 @@ function asCanonicalTurnId(value: TurnId): TurnId { | ... | @@ -353,7 +353,7 @@ function asCanonicalTurnId(value: TurnId): TurnId { |
| 353 | } | 353 | } |
| 354 | 354 | ||
| 355 | function asRuntimeRequestId(value: ApprovalRequestId): RuntimeRequestId { | 355 | function asRuntimeRequestId(value: ApprovalRequestId): RuntimeRequestId { |
| 356 | return RuntimeRequestId.makeUnsafe(value); | 356 | return RuntimeRequestId.make(value); |
| 357 | } | 357 | } |
| 358 | 358 | ||
| 359 | function readClaudeResumeState(resumeCursor: unknown): ClaudeResumeState | undefined { | 359 | function readClaudeResumeState(resumeCursor: unknown): ClaudeResumeState | undefined { |
| ... | @@ -371,7 +371,7 @@ function readClaudeResumeState(resumeCursor: unknown): ClaudeResumeState | undef | ... | @@ -371,7 +371,7 @@ function readClaudeResumeState(resumeCursor: unknown): ClaudeResumeState | undef |
| 371 | const threadIdCandidate = typeof cursor.threadId === "string" ? cursor.threadId : undefined; | 371 | const threadIdCandidate = typeof cursor.threadId === "string" ? cursor.threadId : undefined; |
| 372 | const threadId = | 372 | const threadId = |
| 373 | threadIdCandidate && !isSyntheticClaudeThreadId(threadIdCandidate) | 373 | threadIdCandidate && !isSyntheticClaudeThreadId(threadIdCandidate) |
| 374 | ? ThreadId.makeUnsafe(threadIdCandidate) | 374 | ? ThreadId.make(threadIdCandidate) |
| 375 | : undefined; | 375 | : undefined; |
| 376 | const resumeCandidate = | 376 | const resumeCandidate = |
| 377 | typeof cursor.resume === "string" | 377 | typeof cursor.resume === "string" |
| ... | @@ -641,7 +641,7 @@ function nativeProviderRefs( | ... | @@ -641,7 +641,7 @@ function nativeProviderRefs( |
| 641 | ): NonNullable<ProviderRuntimeEvent["providerRefs"]> { | 641 | ): NonNullable<ProviderRuntimeEvent["providerRefs"]> { |
| 642 | if (options?.providerItemId) { | 642 | if (options?.providerItemId) { |
| 643 | return { | 643 | return { |
| 644 | providerItemId: ProviderItemId.makeUnsafe(options.providerItemId), | 644 | providerItemId: ProviderItemId.make(options.providerItemId), |
| 645 | }; | 645 | }; |
| 646 | } | 646 | } |
| 647 | return {}; | 647 | return {}; |
| ... | @@ -934,7 +934,7 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* ( | ... | @@ -934,7 +934,7 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* ( |
| 934 | const serverSettingsService = yield* ServerSettingsService; | 934 | const serverSettingsService = yield* ServerSettingsService; |
| 935 | 935 | ||
| 936 | const nowIso = Effect.map(DateTime.now, DateTime.formatIso); | 936 | const nowIso = Effect.map(DateTime.now, DateTime.formatIso); |
| 937 | const nextEventId = Effect.map(Random.nextUUIDv4, (id) => EventId.makeUnsafe(id)); | 937 | const nextEventId = Effect.map(Random.nextUUIDv4, (id) => EventId.make(id)); |
| 938 | const makeEventStamp = () => Effect.all({ eventId: nextEventId, createdAt: nowIso }); | 938 | const makeEventStamp = () => Effect.all({ eventId: nextEventId, createdAt: nowIso }); |
| 939 | 939 | ||
| 940 | const offerRuntimeEvent = (event: ProviderRuntimeEvent): Effect.Effect<void> => | 940 | const offerRuntimeEvent = (event: ProviderRuntimeEvent): Effect.Effect<void> => |
| ... | @@ -967,7 +967,7 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* ( | ... | @@ -967,7 +967,7 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* ( |
| 967 | ? { providerThreadId: message.session_id } | 967 | ? { providerThreadId: message.session_id } |
| 968 | : {}), | 968 | : {}), |
| 969 | ...(context.turnState ? { turnId: asCanonicalTurnId(context.turnState.turnId) } : {}), | 969 | ...(context.turnState ? { turnId: asCanonicalTurnId(context.turnState.turnId) } : {}), |
| 970 | ...(itemId ? { itemId: ProviderItemId.makeUnsafe(itemId) } : {}), | 970 | ...(itemId ? { itemId: ProviderItemId.make(itemId) } : {}), |
| 971 | payload: message, | 971 | payload: message, |
| 972 | }, | 972 | }, |
| 973 | }, | 973 | }, |
| ... | @@ -1822,7 +1822,7 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* ( | ... | @@ -1822,7 +1822,7 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* ( |
| 1822 | // Auto-start a synthetic turn for assistant messages that arrive without | 1822 | // Auto-start a synthetic turn for assistant messages that arrive without |
| 1823 | // an active turn (e.g., background agent/subagent responses between user prompts). | 1823 | // an active turn (e.g., background agent/subagent responses between user prompts). |
| 1824 | if (!context.turnState) { | 1824 | if (!context.turnState) { |
| 1825 | const turnId = TurnId.makeUnsafe(yield* Random.nextUUIDv4); | 1825 | const turnId = TurnId.make(yield* Random.nextUUIDv4); |
| 1826 | const startedAt = yield* nowIso; | 1826 | const startedAt = yield* nowIso; |
| 1827 | context.turnState = { | 1827 | context.turnState = { |
| 1828 | turnId, | 1828 | turnId, |
| ... | @@ -2013,7 +2013,7 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* ( | ... | @@ -2013,7 +2013,7 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* ( |
| 2013 | ...base, | 2013 | ...base, |
| 2014 | type: "task.started", | 2014 | type: "task.started", |
| 2015 | payload: { | 2015 | payload: { |
| 2016 | taskId: RuntimeTaskId.makeUnsafe(message.task_id), | 2016 | taskId: RuntimeTaskId.make(message.task_id), |
| 2017 | description: message.description, | 2017 | description: message.description, |
| 2018 | ...(message.task_type ? { taskType: message.task_type } : {}), | 2018 | ...(message.task_type ? { taskType: message.task_type } : {}), |
| 2019 | }, | 2019 | }, |
| ... | @@ -2043,7 +2043,7 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* ( | ... | @@ -2043,7 +2043,7 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* ( |
| 2043 | ...base, | 2043 | ...base, |
| 2044 | type: "task.progress", | 2044 | type: "task.progress", |
| 2045 | payload: { | 2045 | payload: { |
| 2046 | taskId: RuntimeTaskId.makeUnsafe(message.task_id), | 2046 | taskId: RuntimeTaskId.make(message.task_id), |
| 2047 | description: message.description, | 2047 | description: message.description, |
| 2048 | ...(message.summary ? { summary: message.summary } : {}), | 2048 | ...(message.summary ? { summary: message.summary } : {}), |
| 2049 | ...(message.usage ? { usage: message.usage } : {}), | 2049 | ...(message.usage ? { usage: message.usage } : {}), |
| ... | @@ -2075,7 +2075,7 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* ( | ... | @@ -2075,7 +2075,7 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* ( |
| 2075 | ...base, | 2075 | ...base, |
| 2076 | type: "task.completed", | 2076 | type: "task.completed", |
| 2077 | payload: { | 2077 | payload: { |
| 2078 | taskId: RuntimeTaskId.makeUnsafe(message.task_id), | 2078 | taskId: RuntimeTaskId.make(message.task_id), |
| 2079 | status: message.status, | 2079 | status: message.status, |
| 2080 | ...(message.summary ? { summary: message.summary } : {}), | 2080 | ...(message.summary ? { summary: message.summary } : {}), |
| 2081 | ...(message.usage ? { usage: message.usage } : {}), | 2081 | ...(message.usage ? { usage: message.usage } : {}), |
| ... | @@ -2380,9 +2380,9 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* ( | ... | @@ -2380,9 +2380,9 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* ( |
| 2380 | existingResumeSessionId === undefined ? yield* Random.nextUUIDv4 : undefined; | 2380 | existingResumeSessionId === undefined ? yield* Random.nextUUIDv4 : undefined; |
| 2381 | const sessionId = existingResumeSessionId ?? newSessionId; | 2381 | const sessionId = existingResumeSessionId ?? newSessionId; |
| 2382 | 2382 | ||
| 2383 | const services = yield* Effect.services(); | 2383 | const runtimeContext = yield* Effect.context<never>(); |
| 2384 | const runFork = Effect.runForkWith(services); | 2384 | const runFork = Effect.runForkWith(runtimeContext); |
| 2385 | const runPromise = Effect.runPromiseWith(services); | 2385 | const runPromise = Effect.runPromiseWith(runtimeContext); |
| 2386 | 2386 | ||
| 2387 | const promptQueue = yield* Queue.unbounded<PromptQueueItem>(); | 2387 | const promptQueue = yield* Queue.unbounded<PromptQueueItem>(); |
| 2388 | const prompt = Stream.fromQueue(promptQueue).pipe( | 2388 | const prompt = Stream.fromQueue(promptQueue).pipe( |
| ... | @@ -2409,7 +2409,7 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* ( | ... | @@ -2409,7 +2409,7 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* ( |
| 2409 | toolInput: Record<string, unknown>, | 2409 | toolInput: Record<string, unknown>, |
| 2410 | callbackOptions: { readonly signal: AbortSignal; readonly toolUseID?: string }, | 2410 | callbackOptions: { readonly signal: AbortSignal; readonly toolUseID?: string }, |
| 2411 | ) { | 2411 | ) { |
| 2412 | const requestId = ApprovalRequestId.makeUnsafe(yield* Random.nextUUIDv4); | 2412 | const requestId = ApprovalRequestId.make(yield* Random.nextUUIDv4); |
| 2413 | 2413 | ||
| 2414 | // Parse questions from the SDK's AskUserQuestion input. | 2414 | // Parse questions from the SDK's AskUserQuestion input. |
| 2415 | const rawQuestions = Array.isArray(toolInput.questions) ? toolInput.questions : []; | 2415 | const rawQuestions = Array.isArray(toolInput.questions) ? toolInput.questions : []; |
| ... | @@ -2562,7 +2562,7 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* ( | ... | @@ -2562,7 +2562,7 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* ( |
| 2562 | } satisfies PermissionResult; | 2562 | } satisfies PermissionResult; |
| 2563 | } | 2563 | } |
| 2564 | 2564 | ||
| 2565 | const requestId = ApprovalRequestId.makeUnsafe(yield* Random.nextUUIDv4); | 2565 | const requestId = ApprovalRequestId.make(yield* Random.nextUUIDv4); |
| 2566 | const requestType = classifyRequestType(toolName); | 2566 | const requestType = classifyRequestType(toolName); |
| 2567 | const detail = summarizeToolRequest(toolName, toolInput); | 2567 | const detail = summarizeToolRequest(toolName, toolInput); |
| 2568 | const decisionDeferred = yield* Deferred.make<ProviderApprovalDecision>(); | 2568 | const decisionDeferred = yield* Deferred.make<ProviderApprovalDecision>(); |
| ... | @@ -2890,7 +2890,7 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* ( | ... | @@ -2890,7 +2890,7 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* ( |
| 2890 | }); | 2890 | }); |
| 2891 | } | 2891 | } |
| 2892 | 2892 | ||
| 2893 | const turnId = TurnId.makeUnsafe(yield* Random.nextUUIDv4); | 2893 | const turnId = TurnId.make(yield* Random.nextUUIDv4); |
| 2894 | const turnState: ClaudeTurnState = { | 2894 | const turnState: ClaudeTurnState = { |
| 2895 | turnId, | 2895 | turnId, |
| 2896 | startedAt: yield* nowIso, | 2896 | startedAt: yield* nowIso, |
apps/server/src/provider/Layers/CodexAdapter.test.ts+8-8| ... | @@ -28,10 +28,10 @@ import { CodexAdapter } from "../Services/CodexAdapter.ts"; | ... | @@ -28,10 +28,10 @@ import { CodexAdapter } from "../Services/CodexAdapter.ts"; |
| 28 | import { ProviderSessionDirectory } from "../Services/ProviderSessionDirectory.ts"; | 28 | import { ProviderSessionDirectory } from "../Services/ProviderSessionDirectory.ts"; |
| 29 | import { makeCodexAdapterLive } from "./CodexAdapter.ts"; | 29 | import { makeCodexAdapterLive } from "./CodexAdapter.ts"; |
| 30 | 30 | ||
| 31 | const asThreadId = (value: string): ThreadId => ThreadId.makeUnsafe(value); | 31 | const asThreadId = (value: string): ThreadId => ThreadId.make(value); |
| 32 | const asTurnId = (value: string): TurnId => TurnId.makeUnsafe(value); | 32 | const asTurnId = (value: string): TurnId => TurnId.make(value); |
| 33 | const asEventId = (value: string): EventId => EventId.makeUnsafe(value); | 33 | const asEventId = (value: string): EventId => EventId.make(value); |
| 34 | const asItemId = (value: string): ProviderItemId => ProviderItemId.makeUnsafe(value); | 34 | const asItemId = (value: string): ProviderItemId => ProviderItemId.make(value); |
| 35 | 35 | ||
| 36 | class FakeCodexManager extends CodexAppServerManager { | 36 | class FakeCodexManager extends CodexAppServerManager { |
| 37 | public startSessionImpl = vi.fn( | 37 | public startSessionImpl = vi.fn( |
| ... | @@ -556,7 +556,7 @@ lifecycleLayer("CodexAdapterLive lifecycle", (it) => { | ... | @@ -556,7 +556,7 @@ lifecycleLayer("CodexAdapterLive lifecycle", (it) => { |
| 556 | threadId: asThreadId("thread-1"), | 556 | threadId: asThreadId("thread-1"), |
| 557 | createdAt: new Date().toISOString(), | 557 | createdAt: new Date().toISOString(), |
| 558 | method: "serverRequest/resolved", | 558 | method: "serverRequest/resolved", |
| 559 | requestId: ApprovalRequestId.makeUnsafe("req-1"), | 559 | requestId: ApprovalRequestId.make("req-1"), |
| 560 | payload: { | 560 | payload: { |
| 561 | request: { | 561 | request: { |
| 562 | method: "item/commandExecution/requestApproval", | 562 | method: "item/commandExecution/requestApproval", |
| ... | @@ -592,7 +592,7 @@ lifecycleLayer("CodexAdapterLive lifecycle", (it) => { | ... | @@ -592,7 +592,7 @@ lifecycleLayer("CodexAdapterLive lifecycle", (it) => { |
| 592 | threadId: asThreadId("thread-1"), | 592 | threadId: asThreadId("thread-1"), |
| 593 | createdAt: new Date().toISOString(), | 593 | createdAt: new Date().toISOString(), |
| 594 | method: "serverRequest/resolved", | 594 | method: "serverRequest/resolved", |
| 595 | requestId: ApprovalRequestId.makeUnsafe("req-file-read-1"), | 595 | requestId: ApprovalRequestId.make("req-file-read-1"), |
| 596 | payload: { | 596 | payload: { |
| 597 | request: { | 597 | request: { |
| 598 | method: "item/fileRead/requestApproval", | 598 | method: "item/fileRead/requestApproval", |
| ... | @@ -710,7 +710,7 @@ lifecycleLayer("CodexAdapterLive lifecycle", (it) => { | ... | @@ -710,7 +710,7 @@ lifecycleLayer("CodexAdapterLive lifecycle", (it) => { |
| 710 | threadId: asThreadId("thread-1"), | 710 | threadId: asThreadId("thread-1"), |
| 711 | createdAt: new Date().toISOString(), | 711 | createdAt: new Date().toISOString(), |
| 712 | method: "item/tool/requestUserInput", | 712 | method: "item/tool/requestUserInput", |
| 713 | requestId: ApprovalRequestId.makeUnsafe("req-user-input-1"), | 713 | requestId: ApprovalRequestId.make("req-user-input-1"), |
| 714 | payload: { | 714 | payload: { |
| 715 | questions: [ | 715 | questions: [ |
| 716 | { | 716 | { |
| ... | @@ -735,7 +735,7 @@ lifecycleLayer("CodexAdapterLive lifecycle", (it) => { | ... | @@ -735,7 +735,7 @@ lifecycleLayer("CodexAdapterLive lifecycle", (it) => { |
| 735 | threadId: asThreadId("thread-1"), | 735 | threadId: asThreadId("thread-1"), |
| 736 | createdAt: new Date().toISOString(), | 736 | createdAt: new Date().toISOString(), |
| 737 | method: "item/tool/requestUserInput/answered", | 737 | method: "item/tool/requestUserInput/answered", |
| 738 | requestId: ApprovalRequestId.makeUnsafe("req-user-input-1"), | 738 | requestId: ApprovalRequestId.make("req-user-input-1"), |
| 739 | payload: { | 739 | payload: { |
| 740 | answers: { | 740 | answers: { |
| 741 | sandbox_mode: { | 741 | sandbox_mode: { |
apps/server/src/provider/Layers/CodexAdapter.ts+9-9| ... | @@ -22,7 +22,7 @@ import { | ... | @@ -22,7 +22,7 @@ import { |
| 22 | TurnId, | 22 | TurnId, |
| 23 | ProviderSendTurnInput, | 23 | ProviderSendTurnInput, |
| 24 | } from "@t3tools/contracts"; | 24 | } from "@t3tools/contracts"; |
| 25 | import { Effect, FileSystem, Layer, Queue, Schema, ServiceMap, Stream } from "effect"; | 25 | import { Effect, FileSystem, Layer, Queue, Schema, Context, Stream } from "effect"; |
| 26 | 26 | ||
| 27 | import { | 27 | import { |
| 28 | ProviderAdapterProcessError, | 28 | ProviderAdapterProcessError, |
| ... | @@ -46,7 +46,7 @@ const PROVIDER = "codex" as const; | ... | @@ -46,7 +46,7 @@ const PROVIDER = "codex" as const; |
| 46 | 46 | ||
| 47 | export interface CodexAdapterLiveOptions { | 47 | export interface CodexAdapterLiveOptions { |
| 48 | readonly manager?: CodexAppServerManager; | 48 | readonly manager?: CodexAppServerManager; |
| 49 | readonly makeManager?: (services?: ServiceMap.ServiceMap<never>) => CodexAppServerManager; | 49 | readonly makeManager?: (services?: Context.Context<never>) => CodexAppServerManager; |
| 50 | readonly nativeEventLogPath?: string; | 50 | readonly nativeEventLogPath?: string; |
| 51 | readonly nativeEventLogger?: EventNdjsonLogger; | 51 | readonly nativeEventLogger?: EventNdjsonLogger; |
| 52 | } | 52 | } |
| ... | @@ -162,11 +162,11 @@ function normalizeCodexTokenUsage(value: unknown): ThreadTokenUsageSnapshot | un | ... | @@ -162,11 +162,11 @@ function normalizeCodexTokenUsage(value: unknown): ThreadTokenUsageSnapshot | un |
| 162 | } | 162 | } |
| 163 | 163 | ||
| 164 | function toTurnId(value: string | undefined): TurnId | undefined { | 164 | function toTurnId(value: string | undefined): TurnId | undefined { |
| 165 | return value?.trim() ? TurnId.makeUnsafe(value) : undefined; | 165 | return value?.trim() ? TurnId.make(value) : undefined; |
| 166 | } | 166 | } |
| 167 | 167 | ||
| 168 | function toProviderItemId(value: string | undefined): ProviderItemId | undefined { | 168 | function toProviderItemId(value: string | undefined): ProviderItemId | undefined { |
| 169 | return value?.trim() ? ProviderItemId.makeUnsafe(value) : undefined; | 169 | return value?.trim() ? ProviderItemId.make(value) : undefined; |
| 170 | } | 170 | } |
| 171 | 171 | ||
| 172 | function toTurnStatus(value: unknown): "completed" | "failed" | "cancelled" | "interrupted" { | 172 | function toTurnStatus(value: unknown): "completed" | "failed" | "cancelled" | "interrupted" { |
| ... | @@ -454,15 +454,15 @@ function extractProposedPlanMarkdown(text: string | undefined): string | undefin | ... | @@ -454,15 +454,15 @@ function extractProposedPlanMarkdown(text: string | undefined): string | undefin |
| 454 | } | 454 | } |
| 455 | 455 | ||
| 456 | function asRuntimeItemId(itemId: ProviderItemId): RuntimeItemId { | 456 | function asRuntimeItemId(itemId: ProviderItemId): RuntimeItemId { |
| 457 | return RuntimeItemId.makeUnsafe(itemId); | 457 | return RuntimeItemId.make(itemId); |
| 458 | } | 458 | } |
| 459 | 459 | ||
| 460 | function asRuntimeRequestId(requestId: string): RuntimeRequestId { | 460 | function asRuntimeRequestId(requestId: string): RuntimeRequestId { |
| 461 | return RuntimeRequestId.makeUnsafe(requestId); | 461 | return RuntimeRequestId.make(requestId); |
| 462 | } | 462 | } |
| 463 | 463 | ||
| 464 | function asRuntimeTaskId(taskId: string): RuntimeTaskId { | 464 | function asRuntimeTaskId(taskId: string): RuntimeTaskId { |
| 465 | return RuntimeTaskId.makeUnsafe(taskId); | 465 | return RuntimeTaskId.make(taskId); |
| 466 | } | 466 | } |
| 467 | 467 | ||
| 468 | function codexEventMessage( | 468 | function codexEventMessage( |
| ... | @@ -1366,7 +1366,7 @@ const makeCodexAdapter = Effect.fn("makeCodexAdapter")(function* ( | ... | @@ -1366,7 +1366,7 @@ const makeCodexAdapter = Effect.fn("makeCodexAdapter")(function* ( |
| 1366 | if (options?.manager) { | 1366 | if (options?.manager) { |
| 1367 | return options.manager; | 1367 | return options.manager; |
| 1368 | } | 1368 | } |
| 1369 | const services = yield* Effect.services<never>(); | 1369 | const services = yield* Effect.context<never>(); |
| 1370 | return options?.makeManager?.(services) ?? new CodexAppServerManager(services); | 1370 | return options?.makeManager?.(services) ?? new CodexAppServerManager(services); |
| 1371 | }); | 1371 | }); |
| 1372 | 1372 | ||
| ... | @@ -1585,7 +1585,7 @@ const makeCodexAdapter = Effect.fn("makeCodexAdapter")(function* ( | ... | @@ -1585,7 +1585,7 @@ const makeCodexAdapter = Effect.fn("makeCodexAdapter")(function* ( |
| 1585 | }); | 1585 | }); |
| 1586 | 1586 | ||
| 1587 | const registerListener = Effect.fn("registerListener")(function* () { | 1587 | const registerListener = Effect.fn("registerListener")(function* () { |
| 1588 | const services = yield* Effect.services<never>(); | 1588 | const services = yield* Effect.context<never>(); |
| 1589 | const listenerEffect = Effect.fn("listener")(function* (event: ProviderEvent) { | 1589 | const listenerEffect = Effect.fn("listener")(function* (event: ProviderEvent) { |
| 1590 | yield* writeNativeEvent(event); | 1590 | yield* writeNativeEvent(event); |
| 1591 | const runtimeEvents = mapToRuntimeEvents(event, event.threadId); | 1591 | const runtimeEvents = mapToRuntimeEvents(event, event.threadId); |
apps/server/src/provider/Layers/EventNdjsonLogger.test.ts+3-3| ... | @@ -42,11 +42,11 @@ describe("EventNdjsonLogger", () => { | ... | @@ -42,11 +42,11 @@ describe("EventNdjsonLogger", () => { |
| 42 | 42 | ||
| 43 | yield* logger.write( | 43 | yield* logger.write( |
| 44 | { threadId: "provider-thread-1", id: "evt-1" }, | 44 | { threadId: "provider-thread-1", id: "evt-1" }, |
| 45 | ThreadId.makeUnsafe("thread-1"), | 45 | ThreadId.make("thread-1"), |
| 46 | ); | 46 | ); |
| 47 | yield* logger.write( | 47 | yield* logger.write( |
| 48 | { type: "turn.completed", threadId: "provider-thread-2", id: "evt-2" }, | 48 | { type: "turn.completed", threadId: "provider-thread-2", id: "evt-2" }, |
| 49 | ThreadId.makeUnsafe("thread-2"), | 49 | ThreadId.make("thread-2"), |
| 50 | ); | 50 | ); |
| 51 | yield* logger.close(); | 51 | yield* logger.close(); |
| 52 | 52 | ||
| ... | @@ -178,7 +178,7 @@ describe("EventNdjsonLogger", () => { | ... | @@ -178,7 +178,7 @@ describe("EventNdjsonLogger", () => { |
| 178 | id: `evt-${index}`, | 178 | id: `evt-${index}`, |
| 179 | payload: "x".repeat(40), | 179 | payload: "x".repeat(40), |
| 180 | }, | 180 | }, |
| 181 | ThreadId.makeUnsafe("thread-rotate"), | 181 | ThreadId.make("thread-rotate"), |
| 182 | ); | 182 | ); |
| 183 | } | 183 | } |
| 184 | yield* logger.close(); | 184 | yield* logger.close(); |
apps/server/src/provider/Layers/ProviderRegistry.test.ts+1| ... | @@ -44,6 +44,7 @@ function mockHandle(result: { stdout: string; stderr: string; code: number }) { | ... | @@ -44,6 +44,7 @@ function mockHandle(result: { stdout: string; stderr: string; code: number }) { |
| 44 | exitCode: Effect.succeed(ChildProcessSpawner.ExitCode(result.code)), | 44 | exitCode: Effect.succeed(ChildProcessSpawner.ExitCode(result.code)), |
| 45 | isRunning: Effect.succeed(false), | 45 | isRunning: Effect.succeed(false), |
| 46 | kill: () => Effect.void, | 46 | kill: () => Effect.void, |
| 47 | unref: Effect.succeed(Effect.void), | ||
| 47 | stdin: Sink.drain, | 48 | stdin: Sink.drain, |
| 48 | stdout: Stream.make(encoder.encode(result.stdout)), | 49 | stdout: Stream.make(encoder.encode(result.stdout)), |
| 49 | stderr: Stream.make(encoder.encode(result.stderr)), | 50 | stderr: Stream.make(encoder.encode(result.stderr)), |
apps/server/src/provider/Layers/ProviderService.test.ts+6-6| ... | @@ -47,10 +47,10 @@ import { AnalyticsService } from "../../telemetry/Services/AnalyticsService.ts"; | ... | @@ -47,10 +47,10 @@ import { AnalyticsService } from "../../telemetry/Services/AnalyticsService.ts"; |
| 47 | 47 | ||
| 48 | const defaultServerSettingsLayer = ServerSettingsService.layerTest(); | 48 | const defaultServerSettingsLayer = ServerSettingsService.layerTest(); |
| 49 | 49 | ||
| 50 | const asRequestId = (value: string): ApprovalRequestId => ApprovalRequestId.makeUnsafe(value); | 50 | const asRequestId = (value: string): ApprovalRequestId => ApprovalRequestId.make(value); |
| 51 | const asEventId = (value: string): EventId => EventId.makeUnsafe(value); | 51 | const asEventId = (value: string): EventId => EventId.make(value); |
| 52 | const asThreadId = (value: string): ThreadId => ThreadId.makeUnsafe(value); | 52 | const asThreadId = (value: string): ThreadId => ThreadId.make(value); |
| 53 | const asTurnId = (value: string): TurnId => TurnId.makeUnsafe(value); | 53 | const asTurnId = (value: string): TurnId => TurnId.make(value); |
| 54 | 54 | ||
| 55 | type LegacyProviderRuntimeEvent = { | 55 | type LegacyProviderRuntimeEvent = { |
| 56 | readonly type: string; | 56 | readonly type: string; |
| ... | @@ -102,7 +102,7 @@ function makeFakeCodexAdapter(provider: ProviderKind = "codex") { | ... | @@ -102,7 +102,7 @@ function makeFakeCodexAdapter(provider: ProviderKind = "codex") { |
| 102 | 102 | ||
| 103 | return Effect.succeed({ | 103 | return Effect.succeed({ |
| 104 | threadId: input.threadId, | 104 | threadId: input.threadId, |
| 105 | turnId: TurnId.makeUnsafe(`turn-${String(input.threadId)}`), | 105 | turnId: TurnId.make(`turn-${String(input.threadId)}`), |
| 106 | }); | 106 | }); |
| 107 | }, | 107 | }, |
| 108 | ); | 108 | ); |
| ... | @@ -358,7 +358,7 @@ it.effect("ProviderServiceLive keeps persisted resumable sessions on startup", ( | ... | @@ -358,7 +358,7 @@ it.effect("ProviderServiceLive keeps persisted resumable sessions on startup", ( |
| 358 | const directory = yield* ProviderSessionDirectory; | 358 | const directory = yield* ProviderSessionDirectory; |
| 359 | yield* directory.upsert({ | 359 | yield* directory.upsert({ |
| 360 | provider: "codex", | 360 | provider: "codex", |
| 361 | threadId: ThreadId.makeUnsafe("thread-stale"), | 361 | threadId: ThreadId.make("thread-stale"), |
| 362 | }); | 362 | }); |
| 363 | }).pipe(Effect.provide(directoryLayer)); | 363 | }).pipe(Effect.provide(directoryLayer)); |
| 364 | 364 |
apps/server/src/provider/Layers/ProviderSessionDirectory.test.ts+5-5| ... | @@ -36,7 +36,7 @@ it.layer(makeDirectoryLayer(SqlitePersistenceMemory))("ProviderSessionDirectoryL | ... | @@ -36,7 +36,7 @@ it.layer(makeDirectoryLayer(SqlitePersistenceMemory))("ProviderSessionDirectoryL |
| 36 | const directory = yield* ProviderSessionDirectory; | 36 | const directory = yield* ProviderSessionDirectory; |
| 37 | const runtimeRepository = yield* ProviderSessionRuntimeRepository; | 37 | const runtimeRepository = yield* ProviderSessionRuntimeRepository; |
| 38 | 38 | ||
| 39 | const initialThreadId = ThreadId.makeUnsafe("thread-1"); | 39 | const initialThreadId = ThreadId.make("thread-1"); |
| 40 | 40 | ||
| 41 | yield* directory.upsert({ | 41 | yield* directory.upsert({ |
| 42 | provider: "codex", | 42 | provider: "codex", |
| ... | @@ -54,7 +54,7 @@ it.layer(makeDirectoryLayer(SqlitePersistenceMemory))("ProviderSessionDirectoryL | ... | @@ -54,7 +54,7 @@ it.layer(makeDirectoryLayer(SqlitePersistenceMemory))("ProviderSessionDirectoryL |
| 54 | assert.equal(resolvedBinding.value.threadId, initialThreadId); | 54 | assert.equal(resolvedBinding.value.threadId, initialThreadId); |
| 55 | } | 55 | } |
| 56 | 56 | ||
| 57 | const nextThreadId = ThreadId.makeUnsafe("thread-2"); | 57 | const nextThreadId = ThreadId.make("thread-2"); |
| 58 | 58 | ||
| 59 | yield* directory.upsert({ | 59 | yield* directory.upsert({ |
| 60 | provider: "codex", | 60 | provider: "codex", |
| ... | @@ -93,7 +93,7 @@ it.layer(makeDirectoryLayer(SqlitePersistenceMemory))("ProviderSessionDirectoryL | ... | @@ -93,7 +93,7 @@ it.layer(makeDirectoryLayer(SqlitePersistenceMemory))("ProviderSessionDirectoryL |
| 93 | const directory = yield* ProviderSessionDirectory; | 93 | const directory = yield* ProviderSessionDirectory; |
| 94 | const runtimeRepository = yield* ProviderSessionRuntimeRepository; | 94 | const runtimeRepository = yield* ProviderSessionRuntimeRepository; |
| 95 | 95 | ||
| 96 | const threadId = ThreadId.makeUnsafe("thread-runtime"); | 96 | const threadId = ThreadId.make("thread-runtime"); |
| 97 | 97 | ||
| 98 | yield* directory.upsert({ | 98 | yield* directory.upsert({ |
| 99 | provider: "codex", | 99 | provider: "codex", |
| ... | @@ -137,7 +137,7 @@ it.layer(makeDirectoryLayer(SqlitePersistenceMemory))("ProviderSessionDirectoryL | ... | @@ -137,7 +137,7 @@ it.layer(makeDirectoryLayer(SqlitePersistenceMemory))("ProviderSessionDirectoryL |
| 137 | Effect.gen(function* () { | 137 | Effect.gen(function* () { |
| 138 | const directory = yield* ProviderSessionDirectory; | 138 | const directory = yield* ProviderSessionDirectory; |
| 139 | const runtimeRepository = yield* ProviderSessionRuntimeRepository; | 139 | const runtimeRepository = yield* ProviderSessionRuntimeRepository; |
| 140 | const threadId = ThreadId.makeUnsafe("thread-provider-change"); | 140 | const threadId = ThreadId.make("thread-provider-change"); |
| 141 | 141 | ||
| 142 | yield* runtimeRepository.upsert({ | 142 | yield* runtimeRepository.upsert({ |
| 143 | threadId, | 143 | threadId, |
| ... | @@ -169,7 +169,7 @@ it.layer(makeDirectoryLayer(SqlitePersistenceMemory))("ProviderSessionDirectoryL | ... | @@ -169,7 +169,7 @@ it.layer(makeDirectoryLayer(SqlitePersistenceMemory))("ProviderSessionDirectoryL |
| 169 | const dbPath = path.join(tempDir, "orchestration.sqlite"); | 169 | const dbPath = path.join(tempDir, "orchestration.sqlite"); |
| 170 | const directoryLayer = makeDirectoryLayer(makeSqlitePersistenceLive(dbPath)); | 170 | const directoryLayer = makeDirectoryLayer(makeSqlitePersistenceLive(dbPath)); |
| 171 | 171 | ||
| 172 | const threadId = ThreadId.makeUnsafe("thread-restart"); | 172 | const threadId = ThreadId.make("thread-restart"); |
| 173 | 173 | ||
| 174 | yield* Effect.gen(function* () { | 174 | yield* Effect.gen(function* () { |
| 175 | const directory = yield* ProviderSessionDirectory; | 175 | const directory = yield* ProviderSessionDirectory; |
apps/server/src/provider/Services/ClaudeAdapter.ts+3-3| ... | @@ -5,12 +5,12 @@ | ... | @@ -5,12 +5,12 @@ |
| 5 | * provider runtime events. It does not perform cross-provider routing, shared | 5 | * provider runtime events. It does not perform cross-provider routing, shared |
| 6 | * event fan-out, or checkpoint orchestration. | 6 | * event fan-out, or checkpoint orchestration. |
| 7 | * | 7 | * |
| 8 | * Uses Effect `ServiceMap.Service` for dependency injection and returns the | 8 | * Uses Effect `Context.Service` for dependency injection and returns the |
| 9 | * shared provider-adapter error channel with `provider: "claudeAgent"` context. | 9 | * shared provider-adapter error channel with `provider: "claudeAgent"` context. |
| 10 | * | 10 | * |
| 11 | * @module ClaudeAdapter | 11 | * @module ClaudeAdapter |
| 12 | */ | 12 | */ |
| 13 | import { ServiceMap } from "effect"; | 13 | import { Context } from "effect"; |
| 14 | 14 | ||
| 15 | import type { ProviderAdapterError } from "../Errors.ts"; | 15 | import type { ProviderAdapterError } from "../Errors.ts"; |
| 16 | import type { ProviderAdapterShape } from "./ProviderAdapter.ts"; | 16 | import type { ProviderAdapterShape } from "./ProviderAdapter.ts"; |
| ... | @@ -25,6 +25,6 @@ export interface ClaudeAdapterShape extends ProviderAdapterShape<ProviderAdapter | ... | @@ -25,6 +25,6 @@ export interface ClaudeAdapterShape extends ProviderAdapterShape<ProviderAdapter |
| 25 | /** | 25 | /** |
| 26 | * ClaudeAdapter - Service tag for Claude Agent provider adapter operations. | 26 | * ClaudeAdapter - Service tag for Claude Agent provider adapter operations. |
| 27 | */ | 27 | */ |
| 28 | export class ClaudeAdapter extends ServiceMap.Service<ClaudeAdapter, ClaudeAdapterShape>()( | 28 | export class ClaudeAdapter extends Context.Service<ClaudeAdapter, ClaudeAdapterShape>()( |
| 29 | "t3/provider/Services/ClaudeAdapter", | 29 | "t3/provider/Services/ClaudeAdapter", |
| 30 | ) {} | 30 | ) {} |
apps/server/src/provider/Services/ClaudeProvider.ts+2-2| ... | @@ -1,9 +1,9 @@ | ... | @@ -1,9 +1,9 @@ |
| 1 | import { ServiceMap } from "effect"; | 1 | import { Context } from "effect"; |
| 2 | 2 | ||
| 3 | import type { ServerProviderShape } from "./ServerProvider"; | 3 | import type { ServerProviderShape } from "./ServerProvider"; |
| 4 | 4 | ||
| 5 | export interface ClaudeProviderShape extends ServerProviderShape {} | 5 | export interface ClaudeProviderShape extends ServerProviderShape {} |
| 6 | 6 | ||
| 7 | export class ClaudeProvider extends ServiceMap.Service<ClaudeProvider, ClaudeProviderShape>()( | 7 | export class ClaudeProvider extends Context.Service<ClaudeProvider, ClaudeProviderShape>()( |
| 8 | "t3/provider/Services/ClaudeProvider", | 8 | "t3/provider/Services/ClaudeProvider", |
| 9 | ) {} | 9 | ) {} |
apps/server/src/provider/Services/CodexAdapter.ts+3-3| ... | @@ -5,12 +5,12 @@ | ... | @@ -5,12 +5,12 @@ |
| 5 | * Codex provider events. It does not perform cross-provider routing, shared | 5 | * Codex provider events. It does not perform cross-provider routing, shared |
| 6 | * event fan-out, or checkpoint orchestration. | 6 | * event fan-out, or checkpoint orchestration. |
| 7 | * | 7 | * |
| 8 | * Uses Effect `ServiceMap.Service` for dependency injection and returns the | 8 | * Uses Effect `Context.Service` for dependency injection and returns the |
| 9 | * shared provider-adapter error channel with `provider: "codex"` context. | 9 | * shared provider-adapter error channel with `provider: "codex"` context. |
| 10 | * | 10 | * |
| 11 | * @module CodexAdapter | 11 | * @module CodexAdapter |
| 12 | */ | 12 | */ |
| 13 | import { ServiceMap } from "effect"; | 13 | import { Context } from "effect"; |
| 14 | 14 | ||
| 15 | import type { ProviderAdapterError } from "../Errors.ts"; | 15 | import type { ProviderAdapterError } from "../Errors.ts"; |
| 16 | import type { ProviderAdapterShape } from "./ProviderAdapter.ts"; | 16 | import type { ProviderAdapterShape } from "./ProviderAdapter.ts"; |
| ... | @@ -25,6 +25,6 @@ export interface CodexAdapterShape extends ProviderAdapterShape<ProviderAdapterE | ... | @@ -25,6 +25,6 @@ export interface CodexAdapterShape extends ProviderAdapterShape<ProviderAdapterE |
| 25 | /** | 25 | /** |
| 26 | * CodexAdapter - Service tag for Codex provider adapter operations. | 26 | * CodexAdapter - Service tag for Codex provider adapter operations. |
| 27 | */ | 27 | */ |
| 28 | export class CodexAdapter extends ServiceMap.Service<CodexAdapter, CodexAdapterShape>()( | 28 | export class CodexAdapter extends Context.Service<CodexAdapter, CodexAdapterShape>()( |
| 29 | "t3/provider/Services/CodexAdapter", | 29 | "t3/provider/Services/CodexAdapter", |
| 30 | ) {} | 30 | ) {} |
apps/server/src/provider/Services/CodexProvider.ts+2-2| ... | @@ -1,9 +1,9 @@ | ... | @@ -1,9 +1,9 @@ |
| 1 | import { ServiceMap } from "effect"; | 1 | import { Context } from "effect"; |
| 2 | 2 | ||
| 3 | import type { ServerProviderShape } from "./ServerProvider"; | 3 | import type { ServerProviderShape } from "./ServerProvider"; |
| 4 | 4 | ||
| 5 | export interface CodexProviderShape extends ServerProviderShape {} | 5 | export interface CodexProviderShape extends ServerProviderShape {} |
| 6 | 6 | ||
| 7 | export class CodexProvider extends ServiceMap.Service<CodexProvider, CodexProviderShape>()( | 7 | export class CodexProvider extends Context.Service<CodexProvider, CodexProviderShape>()( |
| 8 | "t3/provider/Services/CodexProvider", | 8 | "t3/provider/Services/CodexProvider", |
| 9 | ) {} | 9 | ) {} |
apps/server/src/provider/Services/ProviderAdapterRegistry.ts+2-2| ... | @@ -8,7 +8,7 @@ | ... | @@ -8,7 +8,7 @@ |
| 8 | * @module ProviderAdapterRegistry | 8 | * @module ProviderAdapterRegistry |
| 9 | */ | 9 | */ |
| 10 | import type { ProviderKind } from "@t3tools/contracts"; | 10 | import type { ProviderKind } from "@t3tools/contracts"; |
| 11 | import { ServiceMap } from "effect"; | 11 | import { Context } from "effect"; |
| 12 | import type { Effect } from "effect"; | 12 | import type { Effect } from "effect"; |
| 13 | 13 | ||
| 14 | import type { ProviderAdapterError, ProviderUnsupportedError } from "../Errors.ts"; | 14 | import type { ProviderAdapterError, ProviderUnsupportedError } from "../Errors.ts"; |
| ... | @@ -34,7 +34,7 @@ export interface ProviderAdapterRegistryShape { | ... | @@ -34,7 +34,7 @@ export interface ProviderAdapterRegistryShape { |
| 34 | /** | 34 | /** |
| 35 | * ProviderAdapterRegistry - Service tag for provider adapter lookup. | 35 | * ProviderAdapterRegistry - Service tag for provider adapter lookup. |
| 36 | */ | 36 | */ |
| 37 | export class ProviderAdapterRegistry extends ServiceMap.Service< | 37 | export class ProviderAdapterRegistry extends Context.Service< |
| 38 | ProviderAdapterRegistry, | 38 | ProviderAdapterRegistry, |
| 39 | ProviderAdapterRegistryShape | 39 | ProviderAdapterRegistryShape |
| 40 | >()("t3/provider/Services/ProviderAdapterRegistry") {} | 40 | >()("t3/provider/Services/ProviderAdapterRegistry") {} |
apps/server/src/provider/Services/ProviderRegistry.ts+2-2| ... | @@ -7,7 +7,7 @@ | ... | @@ -7,7 +7,7 @@ |
| 7 | * @module ProviderRegistry | 7 | * @module ProviderRegistry |
| 8 | */ | 8 | */ |
| 9 | import type { ProviderKind, ServerProvider } from "@t3tools/contracts"; | 9 | import type { ProviderKind, ServerProvider } from "@t3tools/contracts"; |
| 10 | import { ServiceMap } from "effect"; | 10 | import { Context } from "effect"; |
| 11 | import type { Effect, Stream } from "effect"; | 11 | import type { Effect, Stream } from "effect"; |
| 12 | 12 | ||
| 13 | export interface ProviderRegistryShape { | 13 | export interface ProviderRegistryShape { |
| ... | @@ -27,6 +27,6 @@ export interface ProviderRegistryShape { | ... | @@ -27,6 +27,6 @@ export interface ProviderRegistryShape { |
| 27 | readonly streamChanges: Stream.Stream<ReadonlyArray<ServerProvider>>; | 27 | readonly streamChanges: Stream.Stream<ReadonlyArray<ServerProvider>>; |
| 28 | } | 28 | } |
| 29 | 29 | ||
| 30 | export class ProviderRegistry extends ServiceMap.Service<ProviderRegistry, ProviderRegistryShape>()( | 30 | export class ProviderRegistry extends Context.Service<ProviderRegistry, ProviderRegistryShape>()( |
| 31 | "t3/provider/Services/ProviderRegistry", | 31 | "t3/provider/Services/ProviderRegistry", |
| 32 | ) {} | 32 | ) {} |
apps/server/src/provider/Services/ProviderService.ts+3-3| ... | @@ -6,7 +6,7 @@ | ... | @@ -6,7 +6,7 @@ |
| 6 | * session-scoped calls via `ProviderSessionDirectory`, and exposes one unified | 6 | * session-scoped calls via `ProviderSessionDirectory`, and exposes one unified |
| 7 | * provider event stream to callers. | 7 | * provider event stream to callers. |
| 8 | * | 8 | * |
| 9 | * Uses Effect `ServiceMap.Service` for dependency injection and returns typed | 9 | * Uses Effect `Context.Service` for dependency injection and returns typed |
| 10 | * domain errors for validation, session, codex, and checkpoint workflows. | 10 | * domain errors for validation, session, codex, and checkpoint workflows. |
| 11 | * | 11 | * |
| 12 | * @module ProviderService | 12 | * @module ProviderService |
| ... | @@ -24,7 +24,7 @@ import type { | ... | @@ -24,7 +24,7 @@ import type { |
| 24 | ThreadId, | 24 | ThreadId, |
| 25 | ProviderTurnStartResult, | 25 | ProviderTurnStartResult, |
| 26 | } from "@t3tools/contracts"; | 26 | } from "@t3tools/contracts"; |
| 27 | import { ServiceMap } from "effect"; | 27 | import { Context } from "effect"; |
| 28 | import type { Effect, Stream } from "effect"; | 28 | import type { Effect, Stream } from "effect"; |
| 29 | 29 | ||
| 30 | import type { ProviderServiceError } from "../Errors.ts"; | 30 | import type { ProviderServiceError } from "../Errors.ts"; |
| ... | @@ -110,6 +110,6 @@ export interface ProviderServiceShape { | ... | @@ -110,6 +110,6 @@ export interface ProviderServiceShape { |
| 110 | /** | 110 | /** |
| 111 | * ProviderService - Service tag for provider orchestration. | 111 | * ProviderService - Service tag for provider orchestration. |
| 112 | */ | 112 | */ |
| 113 | export class ProviderService extends ServiceMap.Service<ProviderService, ProviderServiceShape>()( | 113 | export class ProviderService extends Context.Service<ProviderService, ProviderServiceShape>()( |
| 114 | "t3/provider/Services/ProviderService", | 114 | "t3/provider/Services/ProviderService", |
| 115 | ) {} | 115 | ) {} |
apps/server/src/provider/Services/ProviderSessionDirectory.ts+2-2| ... | @@ -4,7 +4,7 @@ import type { | ... | @@ -4,7 +4,7 @@ import type { |
| 4 | RuntimeMode, | 4 | RuntimeMode, |
| 5 | ThreadId, | 5 | ThreadId, |
| 6 | } from "@t3tools/contracts"; | 6 | } from "@t3tools/contracts"; |
| 7 | import { Option, ServiceMap } from "effect"; | 7 | import { Option, Context } from "effect"; |
| 8 | import type { Effect } from "effect"; | 8 | import type { Effect } from "effect"; |
| 9 | 9 | ||
| 10 | import type { | 10 | import type { |
| ... | @@ -51,7 +51,7 @@ export interface ProviderSessionDirectoryShape { | ... | @@ -51,7 +51,7 @@ export interface ProviderSessionDirectoryShape { |
| 51 | >; | 51 | >; |
| 52 | } | 52 | } |
| 53 | 53 | ||
| 54 | export class ProviderSessionDirectory extends ServiceMap.Service< | 54 | export class ProviderSessionDirectory extends Context.Service< |
| 55 | ProviderSessionDirectory, | 55 | ProviderSessionDirectory, |
| 56 | ProviderSessionDirectoryShape | 56 | ProviderSessionDirectoryShape |
| 57 | >()("t3/provider/Services/ProviderSessionDirectory") {} | 57 | >()("t3/provider/Services/ProviderSessionDirectory") {} |
apps/server/src/server.test.ts+32-32| ... | @@ -101,15 +101,15 @@ import { WorkspacePathsLive } from "./workspace/Layers/WorkspacePaths.ts"; | ... | @@ -101,15 +101,15 @@ import { WorkspacePathsLive } from "./workspace/Layers/WorkspacePaths.ts"; |
| 101 | import { ServerSecretStoreLive } from "./auth/Layers/ServerSecretStore.ts"; | 101 | import { ServerSecretStoreLive } from "./auth/Layers/ServerSecretStore.ts"; |
| 102 | import { ServerAuthLive } from "./auth/Layers/ServerAuth.ts"; | 102 | import { ServerAuthLive } from "./auth/Layers/ServerAuth.ts"; |
| 103 | 103 | ||
| 104 | const defaultProjectId = ProjectId.makeUnsafe("project-default"); | 104 | const defaultProjectId = ProjectId.make("project-default"); |
| 105 | const defaultThreadId = ThreadId.makeUnsafe("thread-default"); | 105 | const defaultThreadId = ThreadId.make("thread-default"); |
| 106 | const defaultDesktopBootstrapToken = "test-desktop-bootstrap-token"; | 106 | const defaultDesktopBootstrapToken = "test-desktop-bootstrap-token"; |
| 107 | const defaultModelSelection = { | 107 | const defaultModelSelection = { |
| 108 | provider: "codex", | 108 | provider: "codex", |
| 109 | model: "gpt-5-codex", | 109 | model: "gpt-5-codex", |
| 110 | } as const; | 110 | } as const; |
| 111 | const testEnvironmentDescriptor = { | 111 | const testEnvironmentDescriptor = { |
| 112 | environmentId: EnvironmentId.makeUnsafe("environment-test"), | 112 | environmentId: EnvironmentId.make("environment-test"), |
| 113 | label: "Test environment", | 113 | label: "Test environment", |
| 114 | platform: { | 114 | platform: { |
| 115 | os: "darwin" as const, | 115 | os: "darwin" as const, |
| ... | @@ -1307,7 +1307,7 @@ it.layer(NodeServices.layer)("server router seam", (it) => { | ... | @@ -1307,7 +1307,7 @@ it.layer(NodeServices.layer)("server router seam", (it) => { |
| 1307 | ); | 1307 | ); |
| 1308 | 1308 | ||
| 1309 | assert.equal(error._tag, "RpcClientError"); | 1309 | assert.equal(error._tag, "RpcClientError"); |
| 1310 | assertInclude(String(error), "401"); | 1310 | assertInclude(String(error), "SocketOpenError"); |
| 1311 | }).pipe(Effect.provide(NodeHttpServer.layerTest)), | 1311 | }).pipe(Effect.provide(NodeHttpServer.layerTest)), |
| 1312 | ); | 1312 | ); |
| 1313 | 1313 | ||
| ... | @@ -2685,7 +2685,7 @@ it.layer(NodeServices.layer)("server router seam", (it) => { | ... | @@ -2685,7 +2685,7 @@ it.layer(NodeServices.layer)("server router seam", (it) => { |
| 2685 | updatedAt: now, | 2685 | updatedAt: now, |
| 2686 | projects: [ | 2686 | projects: [ |
| 2687 | { | 2687 | { |
| 2688 | id: ProjectId.makeUnsafe("project-a"), | 2688 | id: ProjectId.make("project-a"), |
| 2689 | title: "Project A", | 2689 | title: "Project A", |
| 2690 | workspaceRoot: "/tmp/project-a", | 2690 | workspaceRoot: "/tmp/project-a", |
| 2691 | defaultModelSelection, | 2691 | defaultModelSelection, |
| ... | @@ -2697,8 +2697,8 @@ it.layer(NodeServices.layer)("server router seam", (it) => { | ... | @@ -2697,8 +2697,8 @@ it.layer(NodeServices.layer)("server router seam", (it) => { |
| 2697 | ], | 2697 | ], |
| 2698 | threads: [ | 2698 | threads: [ |
| 2699 | { | 2699 | { |
| 2700 | id: ThreadId.makeUnsafe("thread-1"), | 2700 | id: ThreadId.make("thread-1"), |
| 2701 | projectId: ProjectId.makeUnsafe("project-a"), | 2701 | projectId: ProjectId.make("project-a"), |
| 2702 | title: "Thread A", | 2702 | title: "Thread A", |
| 2703 | modelSelection: defaultModelSelection, | 2703 | modelSelection: defaultModelSelection, |
| 2704 | interactionMode: "default" as const, | 2704 | interactionMode: "default" as const, |
| ... | @@ -2731,14 +2731,14 @@ it.layer(NodeServices.layer)("server router seam", (it) => { | ... | @@ -2731,14 +2731,14 @@ it.layer(NodeServices.layer)("server router seam", (it) => { |
| 2731 | checkpointDiffQuery: { | 2731 | checkpointDiffQuery: { |
| 2732 | getTurnDiff: () => | 2732 | getTurnDiff: () => |
| 2733 | Effect.succeed({ | 2733 | Effect.succeed({ |
| 2734 | threadId: ThreadId.makeUnsafe("thread-1"), | 2734 | threadId: ThreadId.make("thread-1"), |
| 2735 | fromTurnCount: 0, | 2735 | fromTurnCount: 0, |
| 2736 | toTurnCount: 1, | 2736 | toTurnCount: 1, |
| 2737 | diff: "turn-diff", | 2737 | diff: "turn-diff", |
| 2738 | }), | 2738 | }), |
| 2739 | getFullThreadDiff: () => | 2739 | getFullThreadDiff: () => |
| 2740 | Effect.succeed({ | 2740 | Effect.succeed({ |
| 2741 | threadId: ThreadId.makeUnsafe("thread-1"), | 2741 | threadId: ThreadId.make("thread-1"), |
| 2742 | fromTurnCount: 0, | 2742 | fromTurnCount: 0, |
| 2743 | toTurnCount: 1, | 2743 | toTurnCount: 1, |
| 2744 | diff: "full-diff", | 2744 | diff: "full-diff", |
| ... | @@ -2757,8 +2757,8 @@ it.layer(NodeServices.layer)("server router seam", (it) => { | ... | @@ -2757,8 +2757,8 @@ it.layer(NodeServices.layer)("server router seam", (it) => { |
| 2757 | withWsRpcClient(wsUrl, (client) => | 2757 | withWsRpcClient(wsUrl, (client) => |
| 2758 | client[ORCHESTRATION_WS_METHODS.dispatchCommand]({ | 2758 | client[ORCHESTRATION_WS_METHODS.dispatchCommand]({ |
| 2759 | type: "thread.session.stop", | 2759 | type: "thread.session.stop", |
| 2760 | commandId: CommandId.makeUnsafe("cmd-1"), | 2760 | commandId: CommandId.make("cmd-1"), |
| 2761 | threadId: ThreadId.makeUnsafe("thread-1"), | 2761 | threadId: ThreadId.make("thread-1"), |
| 2762 | createdAt: now, | 2762 | createdAt: now, |
| 2763 | }), | 2763 | }), |
| 2764 | ), | 2764 | ), |
| ... | @@ -2768,7 +2768,7 @@ it.layer(NodeServices.layer)("server router seam", (it) => { | ... | @@ -2768,7 +2768,7 @@ it.layer(NodeServices.layer)("server router seam", (it) => { |
| 2768 | const turnDiffResult = yield* Effect.scoped( | 2768 | const turnDiffResult = yield* Effect.scoped( |
| 2769 | withWsRpcClient(wsUrl, (client) => | 2769 | withWsRpcClient(wsUrl, (client) => |
| 2770 | client[ORCHESTRATION_WS_METHODS.getTurnDiff]({ | 2770 | client[ORCHESTRATION_WS_METHODS.getTurnDiff]({ |
| 2771 | threadId: ThreadId.makeUnsafe("thread-1"), | 2771 | threadId: ThreadId.make("thread-1"), |
| 2772 | fromTurnCount: 0, | 2772 | fromTurnCount: 0, |
| 2773 | toTurnCount: 1, | 2773 | toTurnCount: 1, |
| 2774 | }), | 2774 | }), |
| ... | @@ -2779,7 +2779,7 @@ it.layer(NodeServices.layer)("server router seam", (it) => { | ... | @@ -2779,7 +2779,7 @@ it.layer(NodeServices.layer)("server router seam", (it) => { |
| 2779 | const fullDiffResult = yield* Effect.scoped( | 2779 | const fullDiffResult = yield* Effect.scoped( |
| 2780 | withWsRpcClient(wsUrl, (client) => | 2780 | withWsRpcClient(wsUrl, (client) => |
| 2781 | client[ORCHESTRATION_WS_METHODS.getFullThreadDiff]({ | 2781 | client[ORCHESTRATION_WS_METHODS.getFullThreadDiff]({ |
| 2782 | threadId: ThreadId.makeUnsafe("thread-1"), | 2782 | threadId: ThreadId.make("thread-1"), |
| 2783 | toTurnCount: 1, | 2783 | toTurnCount: 1, |
| 2784 | }), | 2784 | }), |
| 2785 | ), | 2785 | ), |
| ... | @@ -2818,7 +2818,7 @@ it.layer(NodeServices.layer)("server router seam", (it) => { | ... | @@ -2818,7 +2818,7 @@ it.layer(NodeServices.layer)("server router seam", (it) => { |
| 2818 | readEvents: (_fromSequenceExclusive) => | 2818 | readEvents: (_fromSequenceExclusive) => |
| 2819 | Stream.make({ | 2819 | Stream.make({ |
| 2820 | sequence: 1, | 2820 | sequence: 1, |
| 2821 | eventId: EventId.makeUnsafe("event-1"), | 2821 | eventId: EventId.make("event-1"), |
| 2822 | aggregateKind: "project", | 2822 | aggregateKind: "project", |
| 2823 | aggregateId: defaultProjectId, | 2823 | aggregateId: defaultProjectId, |
| 2824 | occurredAt: "2026-04-05T00:00:00.000Z", | 2824 | occurredAt: "2026-04-05T00:00:00.000Z", |
| ... | @@ -2866,7 +2866,7 @@ it.layer(NodeServices.layer)("server router seam", (it) => { | ... | @@ -2866,7 +2866,7 @@ it.layer(NodeServices.layer)("server router seam", (it) => { |
| 2866 | 2866 | ||
| 2867 | it.effect("closes thread terminals after a successful archive command", () => | 2867 | it.effect("closes thread terminals after a successful archive command", () => |
| 2868 | Effect.gen(function* () { | 2868 | Effect.gen(function* () { |
| 2869 | const threadId = ThreadId.makeUnsafe("thread-archive"); | 2869 | const threadId = ThreadId.make("thread-archive"); |
| 2870 | const closeInputs: Array<Parameters<TerminalManagerShape["close"]>[0]> = []; | 2870 | const closeInputs: Array<Parameters<TerminalManagerShape["close"]>[0]> = []; |
| 2871 | 2871 | ||
| 2872 | yield* buildAppUnderTest({ | 2872 | yield* buildAppUnderTest({ |
| ... | @@ -2888,7 +2888,7 @@ it.layer(NodeServices.layer)("server router seam", (it) => { | ... | @@ -2888,7 +2888,7 @@ it.layer(NodeServices.layer)("server router seam", (it) => { |
| 2888 | withWsRpcClient(wsUrl, (client) => | 2888 | withWsRpcClient(wsUrl, (client) => |
| 2889 | client[ORCHESTRATION_WS_METHODS.dispatchCommand]({ | 2889 | client[ORCHESTRATION_WS_METHODS.dispatchCommand]({ |
| 2890 | type: "thread.archive", | 2890 | type: "thread.archive", |
| 2891 | commandId: CommandId.makeUnsafe("cmd-thread-archive"), | 2891 | commandId: CommandId.make("cmd-thread-archive"), |
| 2892 | threadId, | 2892 | threadId, |
| 2893 | }), | 2893 | }), |
| 2894 | ), | 2894 | ), |
| ... | @@ -2948,10 +2948,10 @@ it.layer(NodeServices.layer)("server router seam", (it) => { | ... | @@ -2948,10 +2948,10 @@ it.layer(NodeServices.layer)("server router seam", (it) => { |
| 2948 | withWsRpcClient(wsUrl, (client) => | 2948 | withWsRpcClient(wsUrl, (client) => |
| 2949 | client[ORCHESTRATION_WS_METHODS.dispatchCommand]({ | 2949 | client[ORCHESTRATION_WS_METHODS.dispatchCommand]({ |
| 2950 | type: "thread.turn.start", | 2950 | type: "thread.turn.start", |
| 2951 | commandId: CommandId.makeUnsafe("cmd-bootstrap-turn-start"), | 2951 | commandId: CommandId.make("cmd-bootstrap-turn-start"), |
| 2952 | threadId: ThreadId.makeUnsafe("thread-bootstrap"), | 2952 | threadId: ThreadId.make("thread-bootstrap"), |
| 2953 | message: { | 2953 | message: { |
| 2954 | messageId: MessageId.makeUnsafe("msg-bootstrap"), | 2954 | messageId: MessageId.make("msg-bootstrap"), |
| 2955 | role: "user", | 2955 | role: "user", |
| 2956 | text: "hello", | 2956 | text: "hello", |
| 2957 | attachments: [], | 2957 | attachments: [], |
| ... | @@ -3000,7 +3000,7 @@ it.layer(NodeServices.layer)("server router seam", (it) => { | ... | @@ -3000,7 +3000,7 @@ it.layer(NodeServices.layer)("server router seam", (it) => { |
| 3000 | path: null, | 3000 | path: null, |
| 3001 | }); | 3001 | }); |
| 3002 | assert.deepEqual(runForThread.mock.calls[0]?.[0], { | 3002 | assert.deepEqual(runForThread.mock.calls[0]?.[0], { |
| 3003 | threadId: ThreadId.makeUnsafe("thread-bootstrap"), | 3003 | threadId: ThreadId.make("thread-bootstrap"), |
| 3004 | projectId: defaultProjectId, | 3004 | projectId: defaultProjectId, |
| 3005 | projectCwd: "/tmp/project", | 3005 | projectCwd: "/tmp/project", |
| 3006 | worktreePath: "/tmp/bootstrap-worktree", | 3006 | worktreePath: "/tmp/bootstrap-worktree", |
| ... | @@ -3063,10 +3063,10 @@ it.layer(NodeServices.layer)("server router seam", (it) => { | ... | @@ -3063,10 +3063,10 @@ it.layer(NodeServices.layer)("server router seam", (it) => { |
| 3063 | withWsRpcClient(wsUrl, (client) => | 3063 | withWsRpcClient(wsUrl, (client) => |
| 3064 | client[ORCHESTRATION_WS_METHODS.dispatchCommand]({ | 3064 | client[ORCHESTRATION_WS_METHODS.dispatchCommand]({ |
| 3065 | type: "thread.turn.start", | 3065 | type: "thread.turn.start", |
| 3066 | commandId: CommandId.makeUnsafe("cmd-bootstrap-turn-start-setup-failure"), | 3066 | commandId: CommandId.make("cmd-bootstrap-turn-start-setup-failure"), |
| 3067 | threadId: ThreadId.makeUnsafe("thread-bootstrap-setup-failure"), | 3067 | threadId: ThreadId.make("thread-bootstrap-setup-failure"), |
| 3068 | message: { | 3068 | message: { |
| 3069 | messageId: MessageId.makeUnsafe("msg-bootstrap-setup-failure"), | 3069 | messageId: MessageId.make("msg-bootstrap-setup-failure"), |
| 3070 | role: "user", | 3070 | role: "user", |
| 3071 | text: "hello", | 3071 | text: "hello", |
| 3072 | attachments: [], | 3072 | attachments: [], |
| ... | @@ -3179,10 +3179,10 @@ it.layer(NodeServices.layer)("server router seam", (it) => { | ... | @@ -3179,10 +3179,10 @@ it.layer(NodeServices.layer)("server router seam", (it) => { |
| 3179 | withWsRpcClient(wsUrl, (client) => | 3179 | withWsRpcClient(wsUrl, (client) => |
| 3180 | client[ORCHESTRATION_WS_METHODS.dispatchCommand]({ | 3180 | client[ORCHESTRATION_WS_METHODS.dispatchCommand]({ |
| 3181 | type: "thread.turn.start", | 3181 | type: "thread.turn.start", |
| 3182 | commandId: CommandId.makeUnsafe("cmd-bootstrap-turn-start-setup-activity-failure"), | 3182 | commandId: CommandId.make("cmd-bootstrap-turn-start-setup-activity-failure"), |
| 3183 | threadId: ThreadId.makeUnsafe("thread-bootstrap-setup-activity-failure"), | 3183 | threadId: ThreadId.make("thread-bootstrap-setup-activity-failure"), |
| 3184 | message: { | 3184 | message: { |
| 3185 | messageId: MessageId.makeUnsafe("msg-bootstrap-setup-activity-failure"), | 3185 | messageId: MessageId.make("msg-bootstrap-setup-activity-failure"), |
| 3186 | role: "user", | 3186 | role: "user", |
| 3187 | text: "hello", | 3187 | text: "hello", |
| 3188 | attachments: [], | 3188 | attachments: [], |
| ... | @@ -3262,10 +3262,10 @@ it.layer(NodeServices.layer)("server router seam", (it) => { | ... | @@ -3262,10 +3262,10 @@ it.layer(NodeServices.layer)("server router seam", (it) => { |
| 3262 | withWsRpcClient(wsUrl, (client) => | 3262 | withWsRpcClient(wsUrl, (client) => |
| 3263 | client[ORCHESTRATION_WS_METHODS.dispatchCommand]({ | 3263 | client[ORCHESTRATION_WS_METHODS.dispatchCommand]({ |
| 3264 | type: "thread.turn.start", | 3264 | type: "thread.turn.start", |
| 3265 | commandId: CommandId.makeUnsafe("cmd-bootstrap-turn-start-defect"), | 3265 | commandId: CommandId.make("cmd-bootstrap-turn-start-defect"), |
| 3266 | threadId: ThreadId.makeUnsafe("thread-bootstrap-defect"), | 3266 | threadId: ThreadId.make("thread-bootstrap-defect"), |
| 3267 | message: { | 3267 | message: { |
| 3268 | messageId: MessageId.makeUnsafe("msg-bootstrap-defect"), | 3268 | messageId: MessageId.make("msg-bootstrap-defect"), |
| 3269 | role: "user", | 3269 | role: "user", |
| 3270 | text: "hello", | 3270 | text: "hello", |
| 3271 | attachments: [], | 3271 | attachments: [], |
| ... | @@ -3311,7 +3311,7 @@ it.layer(NodeServices.layer)("server router seam", (it) => { | ... | @@ -3311,7 +3311,7 @@ it.layer(NodeServices.layer)("server router seam", (it) => { |
| 3311 | () => | 3311 | () => |
| 3312 | Effect.gen(function* () { | 3312 | Effect.gen(function* () { |
| 3313 | const now = new Date().toISOString(); | 3313 | const now = new Date().toISOString(); |
| 3314 | const threadId = ThreadId.makeUnsafe("thread-1"); | 3314 | const threadId = ThreadId.make("thread-1"); |
| 3315 | let replayCursor: number | null = null; | 3315 | let replayCursor: number | null = null; |
| 3316 | const makeEvent = (sequence: number): OrchestrationEvent => | 3316 | const makeEvent = (sequence: number): OrchestrationEvent => |
| 3317 | ({ | 3317 | ({ |
| ... | @@ -3393,7 +3393,7 @@ it.layer(NodeServices.layer)("server router seam", (it) => { | ... | @@ -3393,7 +3393,7 @@ it.layer(NodeServices.layer)("server router seam", (it) => { |
| 3393 | readEvents: () => | 3393 | readEvents: () => |
| 3394 | Stream.make({ | 3394 | Stream.make({ |
| 3395 | sequence: 1, | 3395 | sequence: 1, |
| 3396 | eventId: EventId.makeUnsafe("event-1"), | 3396 | eventId: EventId.make("event-1"), |
| 3397 | aggregateKind: "project", | 3397 | aggregateKind: "project", |
| 3398 | aggregateId: defaultProjectId, | 3398 | aggregateId: defaultProjectId, |
| 3399 | occurredAt: "2026-04-06T00:00:00.000Z", | 3399 | occurredAt: "2026-04-06T00:00:00.000Z", |
| ... | @@ -3464,7 +3464,7 @@ it.layer(NodeServices.layer)("server router seam", (it) => { | ... | @@ -3464,7 +3464,7 @@ it.layer(NodeServices.layer)("server router seam", (it) => { |
| 3464 | }), | 3464 | }), |
| 3465 | streamDomainEvents: Stream.make({ | 3465 | streamDomainEvents: Stream.make({ |
| 3466 | sequence: 1, | 3466 | sequence: 1, |
| 3467 | eventId: EventId.makeUnsafe("event-1"), | 3467 | eventId: EventId.make("event-1"), |
| 3468 | aggregateKind: "project", | 3468 | aggregateKind: "project", |
| 3469 | aggregateId: defaultProjectId, | 3469 | aggregateId: defaultProjectId, |
| 3470 | occurredAt: "2026-04-05T00:00:00.000Z", | 3470 | occurredAt: "2026-04-05T00:00:00.000Z", |
apps/server/src/serverLifecycleEvents.test.ts+1-1| ... | @@ -11,7 +11,7 @@ it.effect( | ... | @@ -11,7 +11,7 @@ it.effect( |
| 11 | Effect.gen(function* () { | 11 | Effect.gen(function* () { |
| 12 | const lifecycleEvents = yield* ServerLifecycleEvents; | 12 | const lifecycleEvents = yield* ServerLifecycleEvents; |
| 13 | const environment = { | 13 | const environment = { |
| 14 | environmentId: EnvironmentId.makeUnsafe("environment-test"), | 14 | environmentId: EnvironmentId.make("environment-test"), |
| 15 | label: "Test environment", | 15 | label: "Test environment", |
| 16 | platform: { os: "darwin" as const, arch: "arm64" as const }, | 16 | platform: { os: "darwin" as const, arch: "arm64" as const }, |
| 17 | serverVersion: "0.0.0-test", | 17 | serverVersion: "0.0.0-test", |
apps/server/src/serverLifecycleEvents.ts+2-2| ... | @@ -1,5 +1,5 @@ | ... | @@ -1,5 +1,5 @@ |
| 1 | import type { ServerLifecycleStreamEvent } from "@t3tools/contracts"; | 1 | import type { ServerLifecycleStreamEvent } from "@t3tools/contracts"; |
| 2 | import { Effect, Layer, PubSub, Ref, ServiceMap, Stream } from "effect"; | 2 | import { Effect, Layer, PubSub, Ref, Context, Stream } from "effect"; |
| 3 | 3 | ||
| 4 | type LifecycleEventInput = | 4 | type LifecycleEventInput = |
| 5 | | Omit<Extract<ServerLifecycleStreamEvent, { type: "welcome" }>, "sequence"> | 5 | | Omit<Extract<ServerLifecycleStreamEvent, { type: "welcome" }>, "sequence"> |
| ... | @@ -16,7 +16,7 @@ export interface ServerLifecycleEventsShape { | ... | @@ -16,7 +16,7 @@ export interface ServerLifecycleEventsShape { |
| 16 | readonly stream: Stream.Stream<ServerLifecycleStreamEvent>; | 16 | readonly stream: Stream.Stream<ServerLifecycleStreamEvent>; |
| 17 | } | 17 | } |
| 18 | 18 | ||
| 19 | export class ServerLifecycleEvents extends ServiceMap.Service< | 19 | export class ServerLifecycleEvents extends Context.Service< |
| 20 | ServerLifecycleEvents, | 20 | ServerLifecycleEvents, |
| 21 | ServerLifecycleEventsShape | 21 | ServerLifecycleEventsShape |
| 22 | >()("t3/serverLifecycleEvents") {} | 22 | >()("t3/serverLifecycleEvents") {} |
apps/server/src/serverRuntimeStartup.ts+6-6| ... | @@ -17,7 +17,7 @@ import { | ... | @@ -17,7 +17,7 @@ import { |
| 17 | Queue, | 17 | Queue, |
| 18 | Ref, | 18 | Ref, |
| 19 | Scope, | 19 | Scope, |
| 20 | ServiceMap, | 20 | Context, |
| 21 | Console, | 21 | Console, |
| 22 | } from "effect"; | 22 | } from "effect"; |
| 23 | 23 | ||
| ... | @@ -52,7 +52,7 @@ export interface ServerRuntimeStartupShape { | ... | @@ -52,7 +52,7 @@ export interface ServerRuntimeStartupShape { |
| 52 | ) => Effect.Effect<A, E | ServerRuntimeStartupError>; | 52 | ) => Effect.Effect<A, E | ServerRuntimeStartupError>; |
| 53 | } | 53 | } |
| 54 | 54 | ||
| 55 | export class ServerRuntimeStartup extends ServiceMap.Service< | 55 | export class ServerRuntimeStartup extends Context.Service< |
| 56 | ServerRuntimeStartup, | 56 | ServerRuntimeStartup, |
| 57 | ServerRuntimeStartupShape | 57 | ServerRuntimeStartupShape |
| 58 | >()("t3/serverRuntimeStartup") {} | 58 | >()("t3/serverRuntimeStartup") {} |
| ... | @@ -176,12 +176,12 @@ const autoBootstrapWelcome = Effect.gen(function* () { | ... | @@ -176,12 +176,12 @@ const autoBootstrapWelcome = Effect.gen(function* () { |
| 176 | 176 | ||
| 177 | if (Option.isNone(existingProject)) { | 177 | if (Option.isNone(existingProject)) { |
| 178 | const createdAt = new Date().toISOString(); | 178 | const createdAt = new Date().toISOString(); |
| 179 | nextProjectId = ProjectId.makeUnsafe(crypto.randomUUID()); | 179 | nextProjectId = ProjectId.make(crypto.randomUUID()); |
| 180 | const bootstrapProjectTitle = path.basename(serverConfig.cwd) || "project"; | 180 | const bootstrapProjectTitle = path.basename(serverConfig.cwd) || "project"; |
| 181 | nextProjectDefaultModelSelection = getAutoBootstrapDefaultModelSelection(); | 181 | nextProjectDefaultModelSelection = getAutoBootstrapDefaultModelSelection(); |
| 182 | yield* orchestrationEngine.dispatch({ | 182 | yield* orchestrationEngine.dispatch({ |
| 183 | type: "project.create", | 183 | type: "project.create", |
| 184 | commandId: CommandId.makeUnsafe(crypto.randomUUID()), | 184 | commandId: CommandId.make(crypto.randomUUID()), |
| 185 | projectId: nextProjectId, | 185 | projectId: nextProjectId, |
| 186 | title: bootstrapProjectTitle, | 186 | title: bootstrapProjectTitle, |
| 187 | workspaceRoot: serverConfig.cwd, | 187 | workspaceRoot: serverConfig.cwd, |
| ... | @@ -198,10 +198,10 @@ const autoBootstrapWelcome = Effect.gen(function* () { | ... | @@ -198,10 +198,10 @@ const autoBootstrapWelcome = Effect.gen(function* () { |
| 198 | yield* projectionReadModelQuery.getFirstActiveThreadIdByProjectId(nextProjectId); | 198 | yield* projectionReadModelQuery.getFirstActiveThreadIdByProjectId(nextProjectId); |
| 199 | if (Option.isNone(existingThreadId)) { | 199 | if (Option.isNone(existingThreadId)) { |
| 200 | const createdAt = new Date().toISOString(); | 200 | const createdAt = new Date().toISOString(); |
| 201 | const createdThreadId = ThreadId.makeUnsafe(crypto.randomUUID()); | 201 | const createdThreadId = ThreadId.make(crypto.randomUUID()); |
| 202 | yield* orchestrationEngine.dispatch({ | 202 | yield* orchestrationEngine.dispatch({ |
| 203 | type: "thread.create", | 203 | type: "thread.create", |
| 204 | commandId: CommandId.makeUnsafe(crypto.randomUUID()), | 204 | commandId: CommandId.make(crypto.randomUUID()), |
| 205 | threadId: createdThreadId, | 205 | threadId: createdThreadId, |
| 206 | projectId: nextProjectId, | 206 | projectId: nextProjectId, |
| 207 | title: "New thread", | 207 | title: "New thread", |
apps/server/src/serverSettings.ts+2-2| ... | @@ -34,7 +34,7 @@ import { | ... | @@ -34,7 +34,7 @@ import { |
| 34 | Schema, | 34 | Schema, |
| 35 | SchemaIssue, | 35 | SchemaIssue, |
| 36 | Scope, | 36 | Scope, |
| 37 | ServiceMap, | 37 | Context, |
| 38 | Stream, | 38 | Stream, |
| 39 | Cause, | 39 | Cause, |
| 40 | } from "effect"; | 40 | } from "effect"; |
| ... | @@ -62,7 +62,7 @@ export interface ServerSettingsShape { | ... | @@ -62,7 +62,7 @@ export interface ServerSettingsShape { |
| 62 | readonly streamChanges: Stream.Stream<ServerSettings>; | 62 | readonly streamChanges: Stream.Stream<ServerSettings>; |
| 63 | } | 63 | } |
| 64 | 64 | ||
| 65 | export class ServerSettingsService extends ServiceMap.Service< | 65 | export class ServerSettingsService extends Context.Service< |
| 66 | ServerSettingsService, | 66 | ServerSettingsService, |
| 67 | ServerSettingsShape | 67 | ServerSettingsShape |
| 68 | >()("t3/serverSettings/ServerSettingsService") { | 68 | >()("t3/serverSettings/ServerSettingsService") { |
apps/server/src/telemetry/Services/AnalyticsService.ts+2-2| ... | @@ -6,7 +6,7 @@ | ... | @@ -6,7 +6,7 @@ |
| 6 | * | 6 | * |
| 7 | * @module AnalyticsService | 7 | * @module AnalyticsService |
| 8 | */ | 8 | */ |
| 9 | import { Effect, Layer, ServiceMap } from "effect"; | 9 | import { Effect, Layer, Context } from "effect"; |
| 10 | 10 | ||
| 11 | export interface AnalyticsServiceShape { | 11 | export interface AnalyticsServiceShape { |
| 12 | /** | 12 | /** |
| ... | @@ -23,7 +23,7 @@ export interface AnalyticsServiceShape { | ... | @@ -23,7 +23,7 @@ export interface AnalyticsServiceShape { |
| 23 | readonly flush: Effect.Effect<void, never>; | 23 | readonly flush: Effect.Effect<void, never>; |
| 24 | } | 24 | } |
| 25 | 25 | ||
| 26 | export class AnalyticsService extends ServiceMap.Service<AnalyticsService, AnalyticsServiceShape>()( | 26 | export class AnalyticsService extends Context.Service<AnalyticsService, AnalyticsServiceShape>()( |
| 27 | "t3/telemetry/Services/AnalyticsService", | 27 | "t3/telemetry/Services/AnalyticsService", |
| 28 | ) { | 28 | ) { |
| 29 | static readonly layerTest = Layer.succeed(AnalyticsService, { | 29 | static readonly layerTest = Layer.succeed(AnalyticsService, { |
apps/server/src/terminal/Layers/Manager.ts+2-2| ... | @@ -664,8 +664,8 @@ const makeTerminalManager = Effect.fn("makeTerminalManager")(function* () { | ... | @@ -664,8 +664,8 @@ const makeTerminalManager = Effect.fn("makeTerminalManager")(function* () { |
| 664 | export const makeTerminalManagerWithOptions = Effect.fn("makeTerminalManagerWithOptions")( | 664 | export const makeTerminalManagerWithOptions = Effect.fn("makeTerminalManagerWithOptions")( |
| 665 | function* (options: TerminalManagerOptions) { | 665 | function* (options: TerminalManagerOptions) { |
| 666 | const fileSystem = yield* FileSystem.FileSystem; | 666 | const fileSystem = yield* FileSystem.FileSystem; |
| 667 | const services = yield* Effect.services(); | 667 | const context = yield* Effect.context<never>(); |
| 668 | const runFork = Effect.runForkWith(services); | 668 | const runFork = Effect.runForkWith(context); |
| 669 | 669 | ||
| 670 | const logsDir = options.logsDir; | 670 | const logsDir = options.logsDir; |
| 671 | const historyLineLimit = options.historyLineLimit ?? DEFAULT_HISTORY_LINE_LIMIT; | 671 | const historyLineLimit = options.historyLineLimit ?? DEFAULT_HISTORY_LINE_LIMIT; |
apps/server/src/terminal/Services/Manager.ts+2-2| ... | @@ -23,7 +23,7 @@ import { | ... | @@ -23,7 +23,7 @@ import { |
| 23 | TerminalWriteInput, | 23 | TerminalWriteInput, |
| 24 | } from "@t3tools/contracts"; | 24 | } from "@t3tools/contracts"; |
| 25 | import { PtyProcess } from "./PTY"; | 25 | import { PtyProcess } from "./PTY"; |
| 26 | import { Effect, ServiceMap } from "effect"; | 26 | import { Effect, Context } from "effect"; |
| 27 | 27 | ||
| 28 | export { | 28 | export { |
| 29 | TerminalCwdError, | 29 | TerminalCwdError, |
| ... | @@ -122,6 +122,6 @@ export interface TerminalManagerShape { | ... | @@ -122,6 +122,6 @@ export interface TerminalManagerShape { |
| 122 | /** | 122 | /** |
| 123 | * TerminalManager - Service tag for terminal session orchestration. | 123 | * TerminalManager - Service tag for terminal session orchestration. |
| 124 | */ | 124 | */ |
| 125 | export class TerminalManager extends ServiceMap.Service<TerminalManager, TerminalManagerShape>()( | 125 | export class TerminalManager extends Context.Service<TerminalManager, TerminalManagerShape>()( |
| 126 | "t3/terminal/Services/Manager/TerminalManager", | 126 | "t3/terminal/Services/Manager/TerminalManager", |
| 127 | ) {} | 127 | ) {} |
apps/server/src/terminal/Services/PTY.ts+2-2| ... | @@ -6,7 +6,7 @@ | ... | @@ -6,7 +6,7 @@ |
| 6 | * | 6 | * |
| 7 | * @module PtyAdapter | 7 | * @module PtyAdapter |
| 8 | */ | 8 | */ |
| 9 | import { Effect, Schema, ServiceMap } from "effect"; | 9 | import { Effect, Schema, Context } from "effect"; |
| 10 | 10 | ||
| 11 | /** | 11 | /** |
| 12 | * PtyError - Error type for PTY adapter operations. | 12 | * PtyError - Error type for PTY adapter operations. |
| ... | @@ -53,6 +53,6 @@ export interface PtyAdapterShape { | ... | @@ -53,6 +53,6 @@ export interface PtyAdapterShape { |
| 53 | /** | 53 | /** |
| 54 | * PtyAdapter - Service tag for PTY process integration. | 54 | * PtyAdapter - Service tag for PTY process integration. |
| 55 | */ | 55 | */ |
| 56 | export class PtyAdapter extends ServiceMap.Service<PtyAdapter, PtyAdapterShape>()( | 56 | export class PtyAdapter extends Context.Service<PtyAdapter, PtyAdapterShape>()( |
| 57 | "t3/terminal/Services/PTY/PtyAdapter", | 57 | "t3/terminal/Services/PTY/PtyAdapter", |
| 58 | ) {} | 58 | ) {} |
apps/server/src/workspace/Layers/WorkspaceEntries.ts+8-6| ... | @@ -430,12 +430,14 @@ export const makeWorkspaceEntries = Effect.gen(function* () { | ... | @@ -430,12 +430,14 @@ export const makeWorkspaceEntries = Effect.gen(function* () { |
| 430 | return yield* buildWorkspaceIndexFromFilesystem(cwd); | 430 | return yield* buildWorkspaceIndexFromFilesystem(cwd); |
| 431 | }); | 431 | }); |
| 432 | 432 | ||
| 433 | const workspaceIndexCache = yield* Cache.makeWith<string, WorkspaceIndex, WorkspaceEntriesError>({ | 433 | const workspaceIndexCache = yield* Cache.makeWith<string, WorkspaceIndex, WorkspaceEntriesError>( |
| 434 | capacity: WORKSPACE_CACHE_MAX_KEYS, | 434 | buildWorkspaceIndex, |
| 435 | lookup: buildWorkspaceIndex, | 435 | { |
| 436 | timeToLive: (exit) => | 436 | capacity: WORKSPACE_CACHE_MAX_KEYS, |
| 437 | Exit.isSuccess(exit) ? Duration.millis(WORKSPACE_CACHE_TTL_MS) : Duration.zero, | 437 | timeToLive: (exit) => |
| 438 | }); | 438 | Exit.isSuccess(exit) ? Duration.millis(WORKSPACE_CACHE_TTL_MS) : Duration.zero, |
| 439 | }, | ||
| 440 | ); | ||
| 439 | 441 | ||
| 440 | const normalizeWorkspaceRoot = Effect.fn("WorkspaceEntries.normalizeWorkspaceRoot")(function* ( | 442 | const normalizeWorkspaceRoot = Effect.fn("WorkspaceEntries.normalizeWorkspaceRoot")(function* ( |
| 441 | cwd: string, | 443 | cwd: string, |
apps/server/src/workspace/Services/WorkspaceEntries.ts+2-2| ... | @@ -6,7 +6,7 @@ | ... | @@ -6,7 +6,7 @@ |
| 6 | * | 6 | * |
| 7 | * @module WorkspaceEntries | 7 | * @module WorkspaceEntries |
| 8 | */ | 8 | */ |
| 9 | import { Schema, ServiceMap } from "effect"; | 9 | import { Schema, Context } from "effect"; |
| 10 | import type { Effect } from "effect"; | 10 | import type { Effect } from "effect"; |
| 11 | 11 | ||
| 12 | import type { ProjectSearchEntriesInput, ProjectSearchEntriesResult } from "@t3tools/contracts"; | 12 | import type { ProjectSearchEntriesInput, ProjectSearchEntriesResult } from "@t3tools/contracts"; |
| ... | @@ -43,6 +43,6 @@ export interface WorkspaceEntriesShape { | ... | @@ -43,6 +43,6 @@ export interface WorkspaceEntriesShape { |
| 43 | /** | 43 | /** |
| 44 | * WorkspaceEntries - Service tag for cached workspace entry search. | 44 | * WorkspaceEntries - Service tag for cached workspace entry search. |
| 45 | */ | 45 | */ |
| 46 | export class WorkspaceEntries extends ServiceMap.Service<WorkspaceEntries, WorkspaceEntriesShape>()( | 46 | export class WorkspaceEntries extends Context.Service<WorkspaceEntries, WorkspaceEntriesShape>()( |
| 47 | "t3/workspace/Services/WorkspaceEntries", | 47 | "t3/workspace/Services/WorkspaceEntries", |
| 48 | ) {} | 48 | ) {} |
apps/server/src/workspace/Services/WorkspaceFileSystem.ts+2-2| ... | @@ -6,7 +6,7 @@ | ... | @@ -6,7 +6,7 @@ |
| 6 | * | 6 | * |
| 7 | * @module WorkspaceFileSystem | 7 | * @module WorkspaceFileSystem |
| 8 | */ | 8 | */ |
| 9 | import { Schema, ServiceMap } from "effect"; | 9 | import { Schema, Context } from "effect"; |
| 10 | import type { Effect } from "effect"; | 10 | import type { Effect } from "effect"; |
| 11 | 11 | ||
| 12 | import type { ProjectWriteFileInput, ProjectWriteFileResult } from "@t3tools/contracts"; | 12 | import type { ProjectWriteFileInput, ProjectWriteFileResult } from "@t3tools/contracts"; |
| ... | @@ -44,7 +44,7 @@ export interface WorkspaceFileSystemShape { | ... | @@ -44,7 +44,7 @@ export interface WorkspaceFileSystemShape { |
| 44 | /** | 44 | /** |
| 45 | * WorkspaceFileSystem - Service tag for workspace file operations. | 45 | * WorkspaceFileSystem - Service tag for workspace file operations. |
| 46 | */ | 46 | */ |
| 47 | export class WorkspaceFileSystem extends ServiceMap.Service< | 47 | export class WorkspaceFileSystem extends Context.Service< |
| 48 | WorkspaceFileSystem, | 48 | WorkspaceFileSystem, |
| 49 | WorkspaceFileSystemShape | 49 | WorkspaceFileSystemShape |
| 50 | >()("t3/workspace/Services/WorkspaceFileSystem") {} | 50 | >()("t3/workspace/Services/WorkspaceFileSystem") {} |
apps/server/src/workspace/Services/WorkspacePaths.ts+2-2| ... | @@ -6,7 +6,7 @@ | ... | @@ -6,7 +6,7 @@ |
| 6 | * | 6 | * |
| 7 | * @module WorkspacePaths | 7 | * @module WorkspacePaths |
| 8 | */ | 8 | */ |
| 9 | import { Schema, ServiceMap } from "effect"; | 9 | import { Schema, Context } from "effect"; |
| 10 | import type { Effect } from "effect"; | 10 | import type { Effect } from "effect"; |
| 11 | 11 | ||
| 12 | export class WorkspaceRootNotExistsError extends Schema.TaggedErrorClass<WorkspaceRootNotExistsError>()( | 12 | export class WorkspaceRootNotExistsError extends Schema.TaggedErrorClass<WorkspaceRootNotExistsError>()( |
| ... | @@ -80,6 +80,6 @@ export interface WorkspacePathsShape { | ... | @@ -80,6 +80,6 @@ export interface WorkspacePathsShape { |
| 80 | /** | 80 | /** |
| 81 | * WorkspacePaths - Service tag for workspace path normalization and resolution. | 81 | * WorkspacePaths - Service tag for workspace path normalization and resolution. |
| 82 | */ | 82 | */ |
| 83 | export class WorkspacePaths extends ServiceMap.Service<WorkspacePaths, WorkspacePathsShape>()( | 83 | export class WorkspacePaths extends Context.Service<WorkspacePaths, WorkspacePathsShape>()( |
| 84 | "t3/workspace/Services/WorkspacePaths", | 84 | "t3/workspace/Services/WorkspacePaths", |
| 85 | ) {} | 85 | ) {} |
apps/server/src/ws.ts+2-2| ... | @@ -128,7 +128,7 @@ const makeWsRpcLayer = (currentSessionId: AuthSessionId) => | ... | @@ -128,7 +128,7 @@ const makeWsRpcLayer = (currentSessionId: AuthSessionId) => |
| 128 | const bootstrapCredentials = yield* BootstrapCredentialService; | 128 | const bootstrapCredentials = yield* BootstrapCredentialService; |
| 129 | const sessions = yield* SessionCredentialService; | 129 | const sessions = yield* SessionCredentialService; |
| 130 | const serverCommandId = (tag: string) => | 130 | const serverCommandId = (tag: string) => |
| 131 | CommandId.makeUnsafe(`server:${tag}:${crypto.randomUUID()}`); | 131 | CommandId.make(`server:${tag}:${crypto.randomUUID()}`); |
| 132 | 132 | ||
| 133 | const loadAuthAccessSnapshot = () => | 133 | const loadAuthAccessSnapshot = () => |
| 134 | Effect.all({ | 134 | Effect.all({ |
| ... | @@ -149,7 +149,7 @@ const makeWsRpcLayer = (currentSessionId: AuthSessionId) => | ... | @@ -149,7 +149,7 @@ const makeWsRpcLayer = (currentSessionId: AuthSessionId) => |
| 149 | commandId: serverCommandId("setup-script-activity"), | 149 | commandId: serverCommandId("setup-script-activity"), |
| 150 | threadId: input.threadId, | 150 | threadId: input.threadId, |
| 151 | activity: { | 151 | activity: { |
| 152 | id: EventId.makeUnsafe(crypto.randomUUID()), | 152 | id: EventId.make(crypto.randomUUID()), |
| 153 | tone: input.tone, | 153 | tone: input.tone, |
| 154 | kind: input.kind, | 154 | kind: input.kind, |
| 155 | summary: input.summary, | 155 | summary: input.summary, |
apps/web/src/clientPersistenceStorage.test.ts+1-1| ... | @@ -1,7 +1,7 @@ | ... | @@ -1,7 +1,7 @@ |
| 1 | import { EnvironmentId, type PersistedSavedEnvironmentRecord } from "@t3tools/contracts"; | 1 | import { EnvironmentId, type PersistedSavedEnvironmentRecord } from "@t3tools/contracts"; |
| 2 | import { afterEach, describe, expect, it, vi } from "vitest"; | 2 | import { afterEach, describe, expect, it, vi } from "vitest"; |
| 3 | 3 | ||
| 4 | const testEnvironmentId = EnvironmentId.makeUnsafe("environment-1"); | 4 | const testEnvironmentId = EnvironmentId.make("environment-1"); |
| 5 | 5 | ||
| 6 | const savedRegistryRecord: PersistedSavedEnvironmentRecord = { | 6 | const savedRegistryRecord: PersistedSavedEnvironmentRecord = { |
| 7 | environmentId: testEnvironmentId, | 7 | environmentId: testEnvironmentId, |
apps/web/src/components/BranchToolbar.logic.test.ts+2-2| ... | @@ -13,8 +13,8 @@ import { | ... | @@ -13,8 +13,8 @@ import { |
| 13 | shouldIncludeBranchPickerItem, | 13 | shouldIncludeBranchPickerItem, |
| 14 | } from "./BranchToolbar.logic"; | 14 | } from "./BranchToolbar.logic"; |
| 15 | 15 | ||
| 16 | const localEnvironmentId = EnvironmentId.makeUnsafe("environment-local"); | 16 | const localEnvironmentId = EnvironmentId.make("environment-local"); |
| 17 | const remoteEnvironmentId = EnvironmentId.makeUnsafe("environment-remote"); | 17 | const remoteEnvironmentId = EnvironmentId.make("environment-remote"); |
| 18 | 18 | ||
| 19 | describe("resolveDraftEnvModeAfterBranchChange", () => { | 19 | describe("resolveDraftEnvModeAfterBranchChange", () => { |
| 20 | it("switches to local mode when returning from an existing worktree to the main worktree", () => { | 20 | it("switches to local mode when returning from an existing worktree to the main worktree", () => { |
apps/web/src/components/ChatView.browser.tsx+7-7| ... | @@ -58,7 +58,7 @@ vi.mock("../lib/gitStatusState", () => ({ | ... | @@ -58,7 +58,7 @@ vi.mock("../lib/gitStatusState", () => ({ |
| 58 | 58 | ||
| 59 | const THREAD_ID = "thread-browser-test" as ThreadId; | 59 | const THREAD_ID = "thread-browser-test" as ThreadId; |
| 60 | const PROJECT_ID = "project-1" as ProjectId; | 60 | const PROJECT_ID = "project-1" as ProjectId; |
| 61 | const LOCAL_ENVIRONMENT_ID = EnvironmentId.makeUnsafe("environment-local"); | 61 | const LOCAL_ENVIRONMENT_ID = EnvironmentId.make("environment-local"); |
| 62 | const THREAD_REF = scopeThreadRef(LOCAL_ENVIRONMENT_ID, THREAD_ID); | 62 | const THREAD_REF = scopeThreadRef(LOCAL_ENVIRONMENT_ID, THREAD_ID); |
| 63 | const THREAD_KEY = scopedThreadKey(THREAD_REF); | 63 | const THREAD_KEY = scopedThreadKey(THREAD_REF); |
| 64 | const UUID_ROUTE_RE = /^\/draft\/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/; | 64 | const UUID_ROUTE_RE = /^\/draft\/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/; |
| ... | @@ -143,7 +143,7 @@ function isoAt(offsetSeconds: number): string { | ... | @@ -143,7 +143,7 @@ function isoAt(offsetSeconds: number): string { |
| 143 | function createBaseServerConfig(): ServerConfig { | 143 | function createBaseServerConfig(): ServerConfig { |
| 144 | return { | 144 | return { |
| 145 | environment: { | 145 | environment: { |
| 146 | environmentId: EnvironmentId.makeUnsafe("environment-local"), | 146 | environmentId: EnvironmentId.make("environment-local"), |
| 147 | label: "Local environment", | 147 | label: "Local environment", |
| 148 | platform: { os: "darwin" as const, arch: "arm64" as const }, | 148 | platform: { os: "darwin" as const, arch: "arm64" as const }, |
| 149 | serverVersion: "0.0.0-test", | 149 | serverVersion: "0.0.0-test", |
| ... | @@ -341,7 +341,7 @@ function buildFixture(snapshot: OrchestrationReadModel): TestFixture { | ... | @@ -341,7 +341,7 @@ function buildFixture(snapshot: OrchestrationReadModel): TestFixture { |
| 341 | serverConfig: createBaseServerConfig(), | 341 | serverConfig: createBaseServerConfig(), |
| 342 | welcome: { | 342 | welcome: { |
| 343 | environment: { | 343 | environment: { |
| 344 | environmentId: EnvironmentId.makeUnsafe("environment-local"), | 344 | environmentId: EnvironmentId.make("environment-local"), |
| 345 | label: "Local environment", | 345 | label: "Local environment", |
| 346 | platform: { os: "darwin" as const, arch: "arm64" as const }, | 346 | platform: { os: "darwin" as const, arch: "arm64" as const }, |
| 347 | serverVersion: "0.0.0-test", | 347 | serverVersion: "0.0.0-test", |
| ... | @@ -402,7 +402,7 @@ function addThreadToSnapshot( | ... | @@ -402,7 +402,7 @@ function addThreadToSnapshot( |
| 402 | function createThreadCreatedEvent(threadId: ThreadId, sequence: number): OrchestrationEvent { | 402 | function createThreadCreatedEvent(threadId: ThreadId, sequence: number): OrchestrationEvent { |
| 403 | return { | 403 | return { |
| 404 | sequence, | 404 | sequence, |
| 405 | eventId: EventId.makeUnsafe(`event-thread-created-${sequence}`), | 405 | eventId: EventId.make(`event-thread-created-${sequence}`), |
| 406 | aggregateKind: "thread", | 406 | aggregateKind: "thread", |
| 407 | aggregateId: threadId, | 407 | aggregateId: threadId, |
| 408 | occurredAt: NOW_ISO, | 408 | occurredAt: NOW_ISO, |
| ... | @@ -432,7 +432,7 @@ function createThreadCreatedEvent(threadId: ThreadId, sequence: number): Orchest | ... | @@ -432,7 +432,7 @@ function createThreadCreatedEvent(threadId: ThreadId, sequence: number): Orchest |
| 432 | function createThreadSessionSetEvent(threadId: ThreadId, sequence: number): OrchestrationEvent { | 432 | function createThreadSessionSetEvent(threadId: ThreadId, sequence: number): OrchestrationEvent { |
| 433 | return { | 433 | return { |
| 434 | sequence, | 434 | sequence, |
| 435 | eventId: EventId.makeUnsafe(`event-thread-session-set-${sequence}`), | 435 | eventId: EventId.make(`event-thread-session-set-${sequence}`), |
| 436 | aggregateKind: "thread", | 436 | aggregateKind: "thread", |
| 437 | aggregateId: threadId, | 437 | aggregateId: threadId, |
| 438 | occurredAt: NOW_ISO, | 438 | occurredAt: NOW_ISO, |
| ... | @@ -498,7 +498,7 @@ function draftIdFromPath(pathname: string) { | ... | @@ -498,7 +498,7 @@ function draftIdFromPath(pathname: string) { |
| 498 | if (!draftId) { | 498 | if (!draftId) { |
| 499 | throw new Error(`Expected thread path, received "${pathname}".`); | 499 | throw new Error(`Expected thread path, received "${pathname}".`); |
| 500 | } | 500 | } |
| 501 | return DraftId.makeUnsafe(draftId); | 501 | return DraftId.make(draftId); |
| 502 | } | 502 | } |
| 503 | 503 | ||
| 504 | function draftThreadIdFor(draftId: ReturnType<typeof draftIdFromPath>): ThreadId { | 504 | function draftThreadIdFor(draftId: ReturnType<typeof draftIdFromPath>): ThreadId { |
| ... | @@ -666,7 +666,7 @@ function createSnapshotWithPendingUserInput(): OrchestrationReadModel { | ... | @@ -666,7 +666,7 @@ function createSnapshotWithPendingUserInput(): OrchestrationReadModel { |
| 666 | interactionMode: "plan", | 666 | interactionMode: "plan", |
| 667 | activities: [ | 667 | activities: [ |
| 668 | { | 668 | { |
| 669 | id: EventId.makeUnsafe("activity-user-input-requested"), | 669 | id: EventId.make("activity-user-input-requested"), |
| 670 | tone: "info", | 670 | tone: "info", |
| 671 | kind: "user-input.requested", | 671 | kind: "user-input.requested", |
| 672 | summary: "User input requested", | 672 | summary: "User input requested", |
apps/web/src/components/ChatView.logic.test.ts+45-56| ... | @@ -15,7 +15,7 @@ import { | ... | @@ -15,7 +15,7 @@ import { |
| 15 | waitForStartedServerThread, | 15 | waitForStartedServerThread, |
| 16 | } from "./ChatView.logic"; | 16 | } from "./ChatView.logic"; |
| 17 | 17 | ||
| 18 | const localEnvironmentId = EnvironmentId.makeUnsafe("environment-local"); | 18 | const localEnvironmentId = EnvironmentId.make("environment-local"); |
| 19 | 19 | ||
| 20 | describe("deriveComposerSendState", () => { | 20 | describe("deriveComposerSendState", () => { |
| 21 | it("treats expired terminal pills as non-sendable content", () => { | 21 | it("treats expired terminal pills as non-sendable content", () => { |
| ... | @@ -25,7 +25,7 @@ describe("deriveComposerSendState", () => { | ... | @@ -25,7 +25,7 @@ describe("deriveComposerSendState", () => { |
| 25 | terminalContexts: [ | 25 | terminalContexts: [ |
| 26 | { | 26 | { |
| 27 | id: "ctx-expired", | 27 | id: "ctx-expired", |
| 28 | threadId: ThreadId.makeUnsafe("thread-1"), | 28 | threadId: ThreadId.make("thread-1"), |
| 29 | terminalId: "default", | 29 | terminalId: "default", |
| 30 | terminalLabel: "Terminal 1", | 30 | terminalLabel: "Terminal 1", |
| 31 | lineStart: 4, | 31 | lineStart: 4, |
| ... | @@ -49,7 +49,7 @@ describe("deriveComposerSendState", () => { | ... | @@ -49,7 +49,7 @@ describe("deriveComposerSendState", () => { |
| 49 | terminalContexts: [ | 49 | terminalContexts: [ |
| 50 | { | 50 | { |
| 51 | id: "ctx-expired", | 51 | id: "ctx-expired", |
| 52 | threadId: ThreadId.makeUnsafe("thread-1"), | 52 | threadId: ThreadId.make("thread-1"), |
| 53 | terminalId: "default", | 53 | terminalId: "default", |
| 54 | terminalLabel: "Terminal 1", | 54 | terminalLabel: "Terminal 1", |
| 55 | lineStart: 4, | 55 | lineStart: 4, |
| ... | @@ -86,23 +86,20 @@ describe("reconcileMountedTerminalThreadIds", () => { | ... | @@ -86,23 +86,20 @@ describe("reconcileMountedTerminalThreadIds", () => { |
| 86 | it("keeps previously mounted open threads and adds the active open thread", () => { | 86 | it("keeps previously mounted open threads and adds the active open thread", () => { |
| 87 | expect( | 87 | expect( |
| 88 | reconcileMountedTerminalThreadIds({ | 88 | reconcileMountedTerminalThreadIds({ |
| 89 | currentThreadIds: [ | 89 | currentThreadIds: [ThreadId.make("thread-hidden"), ThreadId.make("thread-stale")], |
| 90 | ThreadId.makeUnsafe("thread-hidden"), | 90 | openThreadIds: [ThreadId.make("thread-hidden"), ThreadId.make("thread-active")], |
| 91 | ThreadId.makeUnsafe("thread-stale"), | 91 | activeThreadId: ThreadId.make("thread-active"), |
| 92 | ], | ||
| 93 | openThreadIds: [ThreadId.makeUnsafe("thread-hidden"), ThreadId.makeUnsafe("thread-active")], | ||
| 94 | activeThreadId: ThreadId.makeUnsafe("thread-active"), | ||
| 95 | activeThreadTerminalOpen: true, | 92 | activeThreadTerminalOpen: true, |
| 96 | }), | 93 | }), |
| 97 | ).toEqual([ThreadId.makeUnsafe("thread-hidden"), ThreadId.makeUnsafe("thread-active")]); | 94 | ).toEqual([ThreadId.make("thread-hidden"), ThreadId.make("thread-active")]); |
| 98 | }); | 95 | }); |
| 99 | 96 | ||
| 100 | it("drops mounted threads once their terminal drawer is no longer open", () => { | 97 | it("drops mounted threads once their terminal drawer is no longer open", () => { |
| 101 | expect( | 98 | expect( |
| 102 | reconcileMountedTerminalThreadIds({ | 99 | reconcileMountedTerminalThreadIds({ |
| 103 | currentThreadIds: [ThreadId.makeUnsafe("thread-closed")], | 100 | currentThreadIds: [ThreadId.make("thread-closed")], |
| 104 | openThreadIds: [], | 101 | openThreadIds: [], |
| 105 | activeThreadId: ThreadId.makeUnsafe("thread-closed"), | 102 | activeThreadId: ThreadId.make("thread-closed"), |
| 106 | activeThreadTerminalOpen: false, | 103 | activeThreadTerminalOpen: false, |
| 107 | }), | 104 | }), |
| 108 | ).toEqual([]); | 105 | ).toEqual([]); |
| ... | @@ -112,55 +109,47 @@ describe("reconcileMountedTerminalThreadIds", () => { | ... | @@ -112,55 +109,47 @@ describe("reconcileMountedTerminalThreadIds", () => { |
| 112 | expect( | 109 | expect( |
| 113 | reconcileMountedTerminalThreadIds({ | 110 | reconcileMountedTerminalThreadIds({ |
| 114 | currentThreadIds: [ | 111 | currentThreadIds: [ |
| 115 | ThreadId.makeUnsafe("thread-1"), | 112 | ThreadId.make("thread-1"), |
| 116 | ThreadId.makeUnsafe("thread-2"), | 113 | ThreadId.make("thread-2"), |
| 117 | ThreadId.makeUnsafe("thread-3"), | 114 | ThreadId.make("thread-3"), |
| 118 | ], | 115 | ], |
| 119 | openThreadIds: [ | 116 | openThreadIds: [ |
| 120 | ThreadId.makeUnsafe("thread-1"), | 117 | ThreadId.make("thread-1"), |
| 121 | ThreadId.makeUnsafe("thread-2"), | 118 | ThreadId.make("thread-2"), |
| 122 | ThreadId.makeUnsafe("thread-3"), | 119 | ThreadId.make("thread-3"), |
| 123 | ThreadId.makeUnsafe("thread-4"), | 120 | ThreadId.make("thread-4"), |
| 124 | ], | 121 | ], |
| 125 | activeThreadId: ThreadId.makeUnsafe("thread-4"), | 122 | activeThreadId: ThreadId.make("thread-4"), |
| 126 | activeThreadTerminalOpen: true, | 123 | activeThreadTerminalOpen: true, |
| 127 | maxHiddenThreadCount: 2, | 124 | maxHiddenThreadCount: 2, |
| 128 | }), | 125 | }), |
| 129 | ).toEqual([ | 126 | ).toEqual([ThreadId.make("thread-2"), ThreadId.make("thread-3"), ThreadId.make("thread-4")]); |
| 130 | ThreadId.makeUnsafe("thread-2"), | ||
| 131 | ThreadId.makeUnsafe("thread-3"), | ||
| 132 | ThreadId.makeUnsafe("thread-4"), | ||
| 133 | ]); | ||
| 134 | }); | 127 | }); |
| 135 | 128 | ||
| 136 | it("moves the active thread to the end so it is treated as most recently used", () => { | 129 | it("moves the active thread to the end so it is treated as most recently used", () => { |
| 137 | expect( | 130 | expect( |
| 138 | reconcileMountedTerminalThreadIds({ | 131 | reconcileMountedTerminalThreadIds({ |
| 139 | currentThreadIds: [ | 132 | currentThreadIds: [ |
| 140 | ThreadId.makeUnsafe("thread-a"), | 133 | ThreadId.make("thread-a"), |
| 141 | ThreadId.makeUnsafe("thread-b"), | 134 | ThreadId.make("thread-b"), |
| 142 | ThreadId.makeUnsafe("thread-c"), | 135 | ThreadId.make("thread-c"), |
| 143 | ], | 136 | ], |
| 144 | openThreadIds: [ | 137 | openThreadIds: [ |
| 145 | ThreadId.makeUnsafe("thread-a"), | 138 | ThreadId.make("thread-a"), |
| 146 | ThreadId.makeUnsafe("thread-b"), | 139 | ThreadId.make("thread-b"), |
| 147 | ThreadId.makeUnsafe("thread-c"), | 140 | ThreadId.make("thread-c"), |
| 148 | ], | 141 | ], |
| 149 | activeThreadId: ThreadId.makeUnsafe("thread-a"), | 142 | activeThreadId: ThreadId.make("thread-a"), |
| 150 | activeThreadTerminalOpen: true, | 143 | activeThreadTerminalOpen: true, |
| 151 | maxHiddenThreadCount: 2, | 144 | maxHiddenThreadCount: 2, |
| 152 | }), | 145 | }), |
| 153 | ).toEqual([ | 146 | ).toEqual([ThreadId.make("thread-b"), ThreadId.make("thread-c"), ThreadId.make("thread-a")]); |
| 154 | ThreadId.makeUnsafe("thread-b"), | ||
| 155 | ThreadId.makeUnsafe("thread-c"), | ||
| 156 | ThreadId.makeUnsafe("thread-a"), | ||
| 157 | ]); | ||
| 158 | }); | 147 | }); |
| 159 | 148 | ||
| 160 | it("defaults to the hidden mounted terminal cap", () => { | 149 | it("defaults to the hidden mounted terminal cap", () => { |
| 161 | const currentThreadIds = Array.from( | 150 | const currentThreadIds = Array.from( |
| 162 | { length: MAX_HIDDEN_MOUNTED_TERMINAL_THREADS + 2 }, | 151 | { length: MAX_HIDDEN_MOUNTED_TERMINAL_THREADS + 2 }, |
| 163 | (_, index) => ThreadId.makeUnsafe(`thread-${index + 1}`), | 152 | (_, index) => ThreadId.make(`thread-${index + 1}`), |
| 164 | ); | 153 | ); |
| 165 | 154 | ||
| 166 | expect( | 155 | expect( |
| ... | @@ -176,7 +165,7 @@ describe("reconcileMountedTerminalThreadIds", () => { | ... | @@ -176,7 +165,7 @@ describe("reconcileMountedTerminalThreadIds", () => { |
| 176 | 165 | ||
| 177 | describe("shouldWriteThreadErrorToCurrentServerThread", () => { | 166 | describe("shouldWriteThreadErrorToCurrentServerThread", () => { |
| 178 | it("routes errors to the active server thread when route and target match", () => { | 167 | it("routes errors to the active server thread when route and target match", () => { |
| 179 | const threadId = ThreadId.makeUnsafe("thread-1"); | 168 | const threadId = ThreadId.make("thread-1"); |
| 180 | const routeThreadRef = scopeThreadRef(localEnvironmentId, threadId); | 169 | const routeThreadRef = scopeThreadRef(localEnvironmentId, threadId); |
| 181 | 170 | ||
| 182 | expect( | 171 | expect( |
| ... | @@ -192,7 +181,7 @@ describe("shouldWriteThreadErrorToCurrentServerThread", () => { | ... | @@ -192,7 +181,7 @@ describe("shouldWriteThreadErrorToCurrentServerThread", () => { |
| 192 | }); | 181 | }); |
| 193 | 182 | ||
| 194 | it("does not route draft-thread errors into server-backed state", () => { | 183 | it("does not route draft-thread errors into server-backed state", () => { |
| 195 | const threadId = ThreadId.makeUnsafe("thread-1"); | 184 | const threadId = ThreadId.make("thread-1"); |
| 196 | 185 | ||
| 197 | expect( | 186 | expect( |
| 198 | shouldWriteThreadErrorToCurrentServerThread({ | 187 | shouldWriteThreadErrorToCurrentServerThread({ |
| ... | @@ -214,10 +203,10 @@ const makeThread = (input?: { | ... | @@ -214,10 +203,10 @@ const makeThread = (input?: { |
| 214 | completedAt: string | null; | 203 | completedAt: string | null; |
| 215 | } | null; | 204 | } | null; |
| 216 | }): Thread => ({ | 205 | }): Thread => ({ |
| 217 | id: input?.id ?? ThreadId.makeUnsafe("thread-1"), | 206 | id: input?.id ?? ThreadId.make("thread-1"), |
| 218 | environmentId: localEnvironmentId, | 207 | environmentId: localEnvironmentId, |
| 219 | codexThreadId: null, | 208 | codexThreadId: null, |
| 220 | projectId: ProjectId.makeUnsafe("project-1"), | 209 | projectId: ProjectId.make("project-1"), |
| 221 | title: "Thread", | 210 | title: "Thread", |
| 222 | modelSelection: { provider: "codex" as const, model: "gpt-5.4" }, | 211 | modelSelection: { provider: "codex" as const, model: "gpt-5.4" }, |
| 223 | runtimeMode: "full-access" as const, | 212 | runtimeMode: "full-access" as const, |
| ... | @@ -242,7 +231,7 @@ const makeThread = (input?: { | ... | @@ -242,7 +231,7 @@ const makeThread = (input?: { |
| 242 | }); | 231 | }); |
| 243 | 232 | ||
| 244 | function setStoreThreads(threads: ReadonlyArray<ReturnType<typeof makeThread>>) { | 233 | function setStoreThreads(threads: ReadonlyArray<ReturnType<typeof makeThread>>) { |
| 245 | const projectId = ProjectId.makeUnsafe("project-1"); | 234 | const projectId = ProjectId.make("project-1"); |
| 246 | const environmentState: EnvironmentState = { | 235 | const environmentState: EnvironmentState = { |
| 247 | projectIds: [projectId], | 236 | projectIds: [projectId], |
| 248 | projectById: { | 237 | projectById: { |
| ... | @@ -355,12 +344,12 @@ afterEach(() => { | ... | @@ -355,12 +344,12 @@ afterEach(() => { |
| 355 | 344 | ||
| 356 | describe("waitForStartedServerThread", () => { | 345 | describe("waitForStartedServerThread", () => { |
| 357 | it("resolves immediately when the thread is already started", async () => { | 346 | it("resolves immediately when the thread is already started", async () => { |
| 358 | const threadId = ThreadId.makeUnsafe("thread-started"); | 347 | const threadId = ThreadId.make("thread-started"); |
| 359 | setStoreThreads([ | 348 | setStoreThreads([ |
| 360 | makeThread({ | 349 | makeThread({ |
| 361 | id: threadId, | 350 | id: threadId, |
| 362 | latestTurn: { | 351 | latestTurn: { |
| 363 | turnId: TurnId.makeUnsafe("turn-started"), | 352 | turnId: TurnId.make("turn-started"), |
| 364 | state: "running", | 353 | state: "running", |
| 365 | requestedAt: "2026-03-29T00:00:01.000Z", | 354 | requestedAt: "2026-03-29T00:00:01.000Z", |
| 366 | startedAt: "2026-03-29T00:00:01.000Z", | 355 | startedAt: "2026-03-29T00:00:01.000Z", |
| ... | @@ -375,7 +364,7 @@ describe("waitForStartedServerThread", () => { | ... | @@ -375,7 +364,7 @@ describe("waitForStartedServerThread", () => { |
| 375 | }); | 364 | }); |
| 376 | 365 | ||
| 377 | it("waits for the thread to start via subscription updates", async () => { | 366 | it("waits for the thread to start via subscription updates", async () => { |
| 378 | const threadId = ThreadId.makeUnsafe("thread-wait"); | 367 | const threadId = ThreadId.make("thread-wait"); |
| 379 | setStoreThreads([makeThread({ id: threadId })]); | 368 | setStoreThreads([makeThread({ id: threadId })]); |
| 380 | 369 | ||
| 381 | const promise = waitForStartedServerThread(scopeThreadRef(localEnvironmentId, threadId), 500); | 370 | const promise = waitForStartedServerThread(scopeThreadRef(localEnvironmentId, threadId), 500); |
| ... | @@ -384,7 +373,7 @@ describe("waitForStartedServerThread", () => { | ... | @@ -384,7 +373,7 @@ describe("waitForStartedServerThread", () => { |
| 384 | makeThread({ | 373 | makeThread({ |
| 385 | id: threadId, | 374 | id: threadId, |
| 386 | latestTurn: { | 375 | latestTurn: { |
| 387 | turnId: TurnId.makeUnsafe("turn-started"), | 376 | turnId: TurnId.make("turn-started"), |
| 388 | state: "running", | 377 | state: "running", |
| 389 | requestedAt: "2026-03-29T00:00:01.000Z", | 378 | requestedAt: "2026-03-29T00:00:01.000Z", |
| 390 | startedAt: "2026-03-29T00:00:01.000Z", | 379 | startedAt: "2026-03-29T00:00:01.000Z", |
| ... | @@ -397,7 +386,7 @@ describe("waitForStartedServerThread", () => { | ... | @@ -397,7 +386,7 @@ describe("waitForStartedServerThread", () => { |
| 397 | }); | 386 | }); |
| 398 | 387 | ||
| 399 | it("handles the thread starting between the initial read and subscription setup", async () => { | 388 | it("handles the thread starting between the initial read and subscription setup", async () => { |
| 400 | const threadId = ThreadId.makeUnsafe("thread-race"); | 389 | const threadId = ThreadId.make("thread-race"); |
| 401 | setStoreThreads([makeThread({ id: threadId })]); | 390 | setStoreThreads([makeThread({ id: threadId })]); |
| 402 | 391 | ||
| 403 | const originalSubscribe = useStore.subscribe.bind(useStore); | 392 | const originalSubscribe = useStore.subscribe.bind(useStore); |
| ... | @@ -409,7 +398,7 @@ describe("waitForStartedServerThread", () => { | ... | @@ -409,7 +398,7 @@ describe("waitForStartedServerThread", () => { |
| 409 | makeThread({ | 398 | makeThread({ |
| 410 | id: threadId, | 399 | id: threadId, |
| 411 | latestTurn: { | 400 | latestTurn: { |
| 412 | turnId: TurnId.makeUnsafe("turn-race"), | 401 | turnId: TurnId.make("turn-race"), |
| 413 | state: "running", | 402 | state: "running", |
| 414 | requestedAt: "2026-03-29T00:00:01.000Z", | 403 | requestedAt: "2026-03-29T00:00:01.000Z", |
| 415 | startedAt: "2026-03-29T00:00:01.000Z", | 404 | startedAt: "2026-03-29T00:00:01.000Z", |
| ... | @@ -429,7 +418,7 @@ describe("waitForStartedServerThread", () => { | ... | @@ -429,7 +418,7 @@ describe("waitForStartedServerThread", () => { |
| 429 | it("returns false after the timeout when the thread never starts", async () => { | 418 | it("returns false after the timeout when the thread never starts", async () => { |
| 430 | vi.useFakeTimers(); | 419 | vi.useFakeTimers(); |
| 431 | 420 | ||
| 432 | const threadId = ThreadId.makeUnsafe("thread-timeout"); | 421 | const threadId = ThreadId.make("thread-timeout"); |
| 433 | setStoreThreads([makeThread({ id: threadId })]); | 422 | setStoreThreads([makeThread({ id: threadId })]); |
| 434 | const promise = waitForStartedServerThread(scopeThreadRef(localEnvironmentId, threadId), 500); | 423 | const promise = waitForStartedServerThread(scopeThreadRef(localEnvironmentId, threadId), 500); |
| 435 | 424 | ||
| ... | @@ -440,9 +429,9 @@ describe("waitForStartedServerThread", () => { | ... | @@ -440,9 +429,9 @@ describe("waitForStartedServerThread", () => { |
| 440 | }); | 429 | }); |
| 441 | 430 | ||
| 442 | describe("hasServerAcknowledgedLocalDispatch", () => { | 431 | describe("hasServerAcknowledgedLocalDispatch", () => { |
| 443 | const projectId = ProjectId.makeUnsafe("project-1"); | 432 | const projectId = ProjectId.make("project-1"); |
| 444 | const previousLatestTurn = { | 433 | const previousLatestTurn = { |
| 445 | turnId: TurnId.makeUnsafe("turn-1"), | 434 | turnId: TurnId.make("turn-1"), |
| 446 | state: "completed" as const, | 435 | state: "completed" as const, |
| 447 | requestedAt: "2026-03-29T00:00:00.000Z", | 436 | requestedAt: "2026-03-29T00:00:00.000Z", |
| 448 | startedAt: "2026-03-29T00:00:01.000Z", | 437 | startedAt: "2026-03-29T00:00:01.000Z", |
| ... | @@ -460,7 +449,7 @@ describe("hasServerAcknowledgedLocalDispatch", () => { | ... | @@ -460,7 +449,7 @@ describe("hasServerAcknowledgedLocalDispatch", () => { |
| 460 | 449 | ||
| 461 | it("does not clear local dispatch before server state changes", () => { | 450 | it("does not clear local dispatch before server state changes", () => { |
| 462 | const localDispatch = createLocalDispatchSnapshot({ | 451 | const localDispatch = createLocalDispatchSnapshot({ |
| 463 | id: ThreadId.makeUnsafe("thread-1"), | 452 | id: ThreadId.make("thread-1"), |
| 464 | environmentId: localEnvironmentId, | 453 | environmentId: localEnvironmentId, |
| 465 | codexThreadId: null, | 454 | codexThreadId: null, |
| 466 | projectId, | 455 | projectId, |
| ... | @@ -497,7 +486,7 @@ describe("hasServerAcknowledgedLocalDispatch", () => { | ... | @@ -497,7 +486,7 @@ describe("hasServerAcknowledgedLocalDispatch", () => { |
| 497 | 486 | ||
| 498 | it("clears local dispatch when a new turn is already settled", () => { | 487 | it("clears local dispatch when a new turn is already settled", () => { |
| 499 | const localDispatch = createLocalDispatchSnapshot({ | 488 | const localDispatch = createLocalDispatchSnapshot({ |
| 500 | id: ThreadId.makeUnsafe("thread-1"), | 489 | id: ThreadId.make("thread-1"), |
| 501 | environmentId: localEnvironmentId, | 490 | environmentId: localEnvironmentId, |
| 502 | codexThreadId: null, | 491 | codexThreadId: null, |
| 503 | projectId, | 492 | projectId, |
| ... | @@ -525,7 +514,7 @@ describe("hasServerAcknowledgedLocalDispatch", () => { | ... | @@ -525,7 +514,7 @@ describe("hasServerAcknowledgedLocalDispatch", () => { |
| 525 | phase: "ready", | 514 | phase: "ready", |
| 526 | latestTurn: { | 515 | latestTurn: { |
| 527 | ...previousLatestTurn, | 516 | ...previousLatestTurn, |
| 528 | turnId: TurnId.makeUnsafe("turn-2"), | 517 | turnId: TurnId.make("turn-2"), |
| 529 | requestedAt: "2026-03-29T00:01:00.000Z", | 518 | requestedAt: "2026-03-29T00:01:00.000Z", |
| 530 | startedAt: "2026-03-29T00:01:01.000Z", | 519 | startedAt: "2026-03-29T00:01:01.000Z", |
| 531 | completedAt: "2026-03-29T00:01:30.000Z", | 520 | completedAt: "2026-03-29T00:01:30.000Z", |
| ... | @@ -543,7 +532,7 @@ describe("hasServerAcknowledgedLocalDispatch", () => { | ... | @@ -543,7 +532,7 @@ describe("hasServerAcknowledgedLocalDispatch", () => { |
| 543 | 532 | ||
| 544 | it("clears local dispatch when the session changes without an observed running phase", () => { | 533 | it("clears local dispatch when the session changes without an observed running phase", () => { |
| 545 | const localDispatch = createLocalDispatchSnapshot({ | 534 | const localDispatch = createLocalDispatchSnapshot({ |
| 546 | id: ThreadId.makeUnsafe("thread-1"), | 535 | id: ThreadId.make("thread-1"), |
| 547 | environmentId: localEnvironmentId, | 536 | environmentId: localEnvironmentId, |
| 548 | codexThreadId: null, | 537 | codexThreadId: null, |
| 549 | projectId, | 538 | projectId, |
apps/web/src/components/GitActionsControl.browser.tsx+1-1| ... | @@ -4,7 +4,7 @@ import { useState } from "react"; | ... | @@ -4,7 +4,7 @@ import { useState } from "react"; |
| 4 | import { afterEach, describe, expect, it, vi } from "vitest"; | 4 | import { afterEach, describe, expect, it, vi } from "vitest"; |
| 5 | import { render } from "vitest-browser-react"; | 5 | import { render } from "vitest-browser-react"; |
| 6 | 6 | ||
| 7 | const SHARED_THREAD_ID = ThreadId.makeUnsafe("thread-shared"); | 7 | const SHARED_THREAD_ID = ThreadId.make("thread-shared"); |
| 8 | const ENVIRONMENT_A = "environment-local" as never; | 8 | const ENVIRONMENT_A = "environment-local" as never; |
| 9 | const ENVIRONMENT_B = "environment-remote" as never; | 9 | const ENVIRONMENT_B = "environment-remote" as never; |
| 10 | const GIT_CWD = "/repo/project"; | 10 | const GIT_CWD = "/repo/project"; |
apps/web/src/components/KeybindingsToast.browser.tsx+1-1| ... | @@ -37,7 +37,7 @@ vi.mock("../lib/gitStatusState", () => ({ | ... | @@ -37,7 +37,7 @@ vi.mock("../lib/gitStatusState", () => ({ |
| 37 | 37 | ||
| 38 | const THREAD_ID = "thread-kb-toast-test" as ThreadId; | 38 | const THREAD_ID = "thread-kb-toast-test" as ThreadId; |
| 39 | const PROJECT_ID = "project-1" as ProjectId; | 39 | const PROJECT_ID = "project-1" as ProjectId; |
| 40 | const LOCAL_ENVIRONMENT_ID = EnvironmentId.makeUnsafe("environment-local"); | 40 | const LOCAL_ENVIRONMENT_ID = EnvironmentId.make("environment-local"); |
| 41 | const NOW_ISO = "2026-03-04T12:00:00.000Z"; | 41 | const NOW_ISO = "2026-03-04T12:00:00.000Z"; |
| 42 | 42 | ||
| 43 | interface TestFixture { | 43 | interface TestFixture { |
apps/web/src/components/Sidebar.logic.test.ts+109-117| ... | @@ -28,7 +28,7 @@ import { | ... | @@ -28,7 +28,7 @@ import { |
| 28 | type Thread, | 28 | type Thread, |
| 29 | } from "../types"; | 29 | } from "../types"; |
| 30 | 30 | ||
| 31 | const localEnvironmentId = EnvironmentId.makeUnsafe("environment-local"); | 31 | const localEnvironmentId = EnvironmentId.make("environment-local"); |
| 32 | 32 | ||
| 33 | function makeLatestTurn(overrides?: { | 33 | function makeLatestTurn(overrides?: { |
| 34 | completedAt?: string | null; | 34 | completedAt?: string | null; |
| ... | @@ -235,42 +235,42 @@ describe("orderItemsByPreferredIds", () => { | ... | @@ -235,42 +235,42 @@ describe("orderItemsByPreferredIds", () => { |
| 235 | it("keeps preferred ids first, skips stale ids, and preserves the relative order of remaining items", () => { | 235 | it("keeps preferred ids first, skips stale ids, and preserves the relative order of remaining items", () => { |
| 236 | const ordered = orderItemsByPreferredIds({ | 236 | const ordered = orderItemsByPreferredIds({ |
| 237 | items: [ | 237 | items: [ |
| 238 | { id: ProjectId.makeUnsafe("project-1"), name: "One" }, | 238 | { id: ProjectId.make("project-1"), name: "One" }, |
| 239 | { id: ProjectId.makeUnsafe("project-2"), name: "Two" }, | 239 | { id: ProjectId.make("project-2"), name: "Two" }, |
| 240 | { id: ProjectId.makeUnsafe("project-3"), name: "Three" }, | 240 | { id: ProjectId.make("project-3"), name: "Three" }, |
| 241 | ], | 241 | ], |
| 242 | preferredIds: [ | 242 | preferredIds: [ |
| 243 | ProjectId.makeUnsafe("project-3"), | 243 | ProjectId.make("project-3"), |
| 244 | ProjectId.makeUnsafe("project-missing"), | 244 | ProjectId.make("project-missing"), |
| 245 | ProjectId.makeUnsafe("project-1"), | 245 | ProjectId.make("project-1"), |
| 246 | ], | 246 | ], |
| 247 | getId: (project) => project.id, | 247 | getId: (project) => project.id, |
| 248 | }); | 248 | }); |
| 249 | 249 | ||
| 250 | expect(ordered.map((project) => project.id)).toEqual([ | 250 | expect(ordered.map((project) => project.id)).toEqual([ |
| 251 | ProjectId.makeUnsafe("project-3"), | 251 | ProjectId.make("project-3"), |
| 252 | ProjectId.makeUnsafe("project-1"), | 252 | ProjectId.make("project-1"), |
| 253 | ProjectId.makeUnsafe("project-2"), | 253 | ProjectId.make("project-2"), |
| 254 | ]); | 254 | ]); |
| 255 | }); | 255 | }); |
| 256 | 256 | ||
| 257 | it("does not duplicate items when preferred ids repeat", () => { | 257 | it("does not duplicate items when preferred ids repeat", () => { |
| 258 | const ordered = orderItemsByPreferredIds({ | 258 | const ordered = orderItemsByPreferredIds({ |
| 259 | items: [ | 259 | items: [ |
| 260 | { id: ProjectId.makeUnsafe("project-1"), name: "One" }, | 260 | { id: ProjectId.make("project-1"), name: "One" }, |
| 261 | { id: ProjectId.makeUnsafe("project-2"), name: "Two" }, | 261 | { id: ProjectId.make("project-2"), name: "Two" }, |
| 262 | ], | 262 | ], |
| 263 | preferredIds: [ | 263 | preferredIds: [ |
| 264 | ProjectId.makeUnsafe("project-2"), | 264 | ProjectId.make("project-2"), |
| 265 | ProjectId.makeUnsafe("project-1"), | 265 | ProjectId.make("project-1"), |
| 266 | ProjectId.makeUnsafe("project-2"), | 266 | ProjectId.make("project-2"), |
| 267 | ], | 267 | ], |
| 268 | getId: (project) => project.id, | 268 | getId: (project) => project.id, |
| 269 | }); | 269 | }); |
| 270 | 270 | ||
| 271 | expect(ordered.map((project) => project.id)).toEqual([ | 271 | expect(ordered.map((project) => project.id)).toEqual([ |
| 272 | ProjectId.makeUnsafe("project-2"), | 272 | ProjectId.make("project-2"), |
| 273 | ProjectId.makeUnsafe("project-1"), | 273 | ProjectId.make("project-1"), |
| 274 | ]); | 274 | ]); |
| 275 | }); | 275 | }); |
| 276 | }); | 276 | }); |
| ... | @@ -278,9 +278,9 @@ describe("orderItemsByPreferredIds", () => { | ... | @@ -278,9 +278,9 @@ describe("orderItemsByPreferredIds", () => { |
| 278 | describe("resolveAdjacentThreadId", () => { | 278 | describe("resolveAdjacentThreadId", () => { |
| 279 | it("resolves adjacent thread ids in ordered sidebar traversal", () => { | 279 | it("resolves adjacent thread ids in ordered sidebar traversal", () => { |
| 280 | const threads = [ | 280 | const threads = [ |
| 281 | ThreadId.makeUnsafe("thread-1"), | 281 | ThreadId.make("thread-1"), |
| 282 | ThreadId.makeUnsafe("thread-2"), | 282 | ThreadId.make("thread-2"), |
| 283 | ThreadId.makeUnsafe("thread-3"), | 283 | ThreadId.make("thread-3"), |
| 284 | ]; | 284 | ]; |
| 285 | 285 | ||
| 286 | expect( | 286 | expect( |
| ... | @@ -327,21 +327,21 @@ describe("getVisibleSidebarThreadIds", () => { | ... | @@ -327,21 +327,21 @@ describe("getVisibleSidebarThreadIds", () => { |
| 327 | getVisibleSidebarThreadIds([ | 327 | getVisibleSidebarThreadIds([ |
| 328 | { | 328 | { |
| 329 | renderedThreadIds: [ | 329 | renderedThreadIds: [ |
| 330 | ThreadId.makeUnsafe("thread-12"), | 330 | ThreadId.make("thread-12"), |
| 331 | ThreadId.makeUnsafe("thread-11"), | 331 | ThreadId.make("thread-11"), |
| 332 | ThreadId.makeUnsafe("thread-10"), | 332 | ThreadId.make("thread-10"), |
| 333 | ], | 333 | ], |
| 334 | }, | 334 | }, |
| 335 | { | 335 | { |
| 336 | renderedThreadIds: [ThreadId.makeUnsafe("thread-8"), ThreadId.makeUnsafe("thread-6")], | 336 | renderedThreadIds: [ThreadId.make("thread-8"), ThreadId.make("thread-6")], |
| 337 | }, | 337 | }, |
| 338 | ]), | 338 | ]), |
| 339 | ).toEqual([ | 339 | ).toEqual([ |
| 340 | ThreadId.makeUnsafe("thread-12"), | 340 | ThreadId.make("thread-12"), |
| 341 | ThreadId.makeUnsafe("thread-11"), | 341 | ThreadId.make("thread-11"), |
| 342 | ThreadId.makeUnsafe("thread-10"), | 342 | ThreadId.make("thread-10"), |
| 343 | ThreadId.makeUnsafe("thread-8"), | 343 | ThreadId.make("thread-8"), |
| 344 | ThreadId.makeUnsafe("thread-6"), | 344 | ThreadId.make("thread-6"), |
| 345 | ]); | 345 | ]); |
| 346 | }); | 346 | }); |
| 347 | 347 | ||
| ... | @@ -350,17 +350,14 @@ describe("getVisibleSidebarThreadIds", () => { | ... | @@ -350,17 +350,14 @@ describe("getVisibleSidebarThreadIds", () => { |
| 350 | getVisibleSidebarThreadIds([ | 350 | getVisibleSidebarThreadIds([ |
| 351 | { | 351 | { |
| 352 | shouldShowThreadPanel: false, | 352 | shouldShowThreadPanel: false, |
| 353 | renderedThreadIds: [ | 353 | renderedThreadIds: [ThreadId.make("thread-hidden-2"), ThreadId.make("thread-hidden-1")], |
| 354 | ThreadId.makeUnsafe("thread-hidden-2"), | ||
| 355 | ThreadId.makeUnsafe("thread-hidden-1"), | ||
| 356 | ], | ||
| 357 | }, | 354 | }, |
| 358 | { | 355 | { |
| 359 | shouldShowThreadPanel: true, | 356 | shouldShowThreadPanel: true, |
| 360 | renderedThreadIds: [ThreadId.makeUnsafe("thread-12"), ThreadId.makeUnsafe("thread-11")], | 357 | renderedThreadIds: [ThreadId.make("thread-12"), ThreadId.make("thread-11")], |
| 361 | }, | 358 | }, |
| 362 | ]), | 359 | ]), |
| 363 | ).toEqual([ThreadId.makeUnsafe("thread-12"), ThreadId.makeUnsafe("thread-11")]); | 360 | ).toEqual([ThreadId.make("thread-12"), ThreadId.make("thread-11")]); |
| 364 | }); | 361 | }); |
| 365 | }); | 362 | }); |
| 366 | 363 | ||
| ... | @@ -574,43 +571,41 @@ describe("getVisibleThreadsForProject", () => { | ... | @@ -574,43 +571,41 @@ describe("getVisibleThreadsForProject", () => { |
| 574 | it("includes the active thread even when it falls below the folded preview", () => { | 571 | it("includes the active thread even when it falls below the folded preview", () => { |
| 575 | const threads = Array.from({ length: 8 }, (_, index) => | 572 | const threads = Array.from({ length: 8 }, (_, index) => |
| 576 | makeThread({ | 573 | makeThread({ |
| 577 | id: ThreadId.makeUnsafe(`thread-${index + 1}`), | 574 | id: ThreadId.make(`thread-${index + 1}`), |
| 578 | title: `Thread ${index + 1}`, | 575 | title: `Thread ${index + 1}`, |
| 579 | }), | 576 | }), |
| 580 | ); | 577 | ); |
| 581 | 578 | ||
| 582 | const result = getVisibleThreadsForProject({ | 579 | const result = getVisibleThreadsForProject({ |
| 583 | threads, | 580 | threads, |
| 584 | activeThreadId: ThreadId.makeUnsafe("thread-8"), | 581 | activeThreadId: ThreadId.make("thread-8"), |
| 585 | isThreadListExpanded: false, | 582 | isThreadListExpanded: false, |
| 586 | previewLimit: 6, | 583 | previewLimit: 6, |
| 587 | }); | 584 | }); |
| 588 | 585 | ||
| 589 | expect(result.hasHiddenThreads).toBe(true); | 586 | expect(result.hasHiddenThreads).toBe(true); |
| 590 | expect(result.visibleThreads.map((thread) => thread.id)).toEqual([ | 587 | expect(result.visibleThreads.map((thread) => thread.id)).toEqual([ |
| 591 | ThreadId.makeUnsafe("thread-1"), | 588 | ThreadId.make("thread-1"), |
| 592 | ThreadId.makeUnsafe("thread-2"), | 589 | ThreadId.make("thread-2"), |
| 593 | ThreadId.makeUnsafe("thread-3"), | 590 | ThreadId.make("thread-3"), |
| 594 | ThreadId.makeUnsafe("thread-4"), | 591 | ThreadId.make("thread-4"), |
| 595 | ThreadId.makeUnsafe("thread-5"), | 592 | ThreadId.make("thread-5"), |
| 596 | ThreadId.makeUnsafe("thread-6"), | 593 | ThreadId.make("thread-6"), |
| 597 | ThreadId.makeUnsafe("thread-8"), | 594 | ThreadId.make("thread-8"), |
| 598 | ]); | ||
| 599 | expect(result.hiddenThreads.map((thread) => thread.id)).toEqual([ | ||
| 600 | ThreadId.makeUnsafe("thread-7"), | ||
| 601 | ]); | 595 | ]); |
| 596 | expect(result.hiddenThreads.map((thread) => thread.id)).toEqual([ThreadId.make("thread-7")]); | ||
| 602 | }); | 597 | }); |
| 603 | 598 | ||
| 604 | it("returns all threads when the list is expanded", () => { | 599 | it("returns all threads when the list is expanded", () => { |
| 605 | const threads = Array.from({ length: 8 }, (_, index) => | 600 | const threads = Array.from({ length: 8 }, (_, index) => |
| 606 | makeThread({ | 601 | makeThread({ |
| 607 | id: ThreadId.makeUnsafe(`thread-${index + 1}`), | 602 | id: ThreadId.make(`thread-${index + 1}`), |
| 608 | }), | 603 | }), |
| 609 | ); | 604 | ); |
| 610 | 605 | ||
| 611 | const result = getVisibleThreadsForProject({ | 606 | const result = getVisibleThreadsForProject({ |
| 612 | threads, | 607 | threads, |
| 613 | activeThreadId: ThreadId.makeUnsafe("thread-8"), | 608 | activeThreadId: ThreadId.make("thread-8"), |
| 614 | isThreadListExpanded: true, | 609 | isThreadListExpanded: true, |
| 615 | previewLimit: 6, | 610 | previewLimit: 6, |
| 616 | }); | 611 | }); |
| ... | @@ -626,7 +621,7 @@ describe("getVisibleThreadsForProject", () => { | ... | @@ -626,7 +621,7 @@ describe("getVisibleThreadsForProject", () => { |
| 626 | function makeProject(overrides: Partial<Project> = {}): Project { | 621 | function makeProject(overrides: Partial<Project> = {}): Project { |
| 627 | const { defaultModelSelection, ...rest } = overrides; | 622 | const { defaultModelSelection, ...rest } = overrides; |
| 628 | return { | 623 | return { |
| 629 | id: ProjectId.makeUnsafe("project-1"), | 624 | id: ProjectId.make("project-1"), |
| 630 | environmentId: localEnvironmentId, | 625 | environmentId: localEnvironmentId, |
| 631 | name: "Project", | 626 | name: "Project", |
| 632 | cwd: "/tmp/project", | 627 | cwd: "/tmp/project", |
| ... | @@ -644,10 +639,10 @@ function makeProject(overrides: Partial<Project> = {}): Project { | ... | @@ -644,10 +639,10 @@ function makeProject(overrides: Partial<Project> = {}): Project { |
| 644 | 639 | ||
| 645 | function makeThread(overrides: Partial<Thread> = {}): Thread { | 640 | function makeThread(overrides: Partial<Thread> = {}): Thread { |
| 646 | return { | 641 | return { |
| 647 | id: ThreadId.makeUnsafe("thread-1"), | 642 | id: ThreadId.make("thread-1"), |
| 648 | environmentId: localEnvironmentId, | 643 | environmentId: localEnvironmentId, |
| 649 | codexThreadId: null, | 644 | codexThreadId: null, |
| 650 | projectId: ProjectId.makeUnsafe("project-1"), | 645 | projectId: ProjectId.make("project-1"), |
| 651 | title: "Thread", | 646 | title: "Thread", |
| 652 | modelSelection: { | 647 | modelSelection: { |
| 653 | provider: "codex", | 648 | provider: "codex", |
| ... | @@ -677,7 +672,7 @@ describe("sortThreadsForSidebar", () => { | ... | @@ -677,7 +672,7 @@ describe("sortThreadsForSidebar", () => { |
| 677 | const sorted = sortThreadsForSidebar( | 672 | const sorted = sortThreadsForSidebar( |
| 678 | [ | 673 | [ |
| 679 | makeThread({ | 674 | makeThread({ |
| 680 | id: ThreadId.makeUnsafe("thread-1"), | 675 | id: ThreadId.make("thread-1"), |
| 681 | createdAt: "2026-03-09T10:00:00.000Z", | 676 | createdAt: "2026-03-09T10:00:00.000Z", |
| 682 | updatedAt: "2026-03-09T10:10:00.000Z", | 677 | updatedAt: "2026-03-09T10:10:00.000Z", |
| 683 | messages: [ | 678 | messages: [ |
| ... | @@ -692,7 +687,7 @@ describe("sortThreadsForSidebar", () => { | ... | @@ -692,7 +687,7 @@ describe("sortThreadsForSidebar", () => { |
| 692 | ], | 687 | ], |
| 693 | }), | 688 | }), |
| 694 | makeThread({ | 689 | makeThread({ |
| 695 | id: ThreadId.makeUnsafe("thread-2"), | 690 | id: ThreadId.make("thread-2"), |
| 696 | createdAt: "2026-03-09T10:05:00.000Z", | 691 | createdAt: "2026-03-09T10:05:00.000Z", |
| 697 | updatedAt: "2026-03-09T10:05:00.000Z", | 692 | updatedAt: "2026-03-09T10:05:00.000Z", |
| 698 | messages: [ | 693 | messages: [ |
| ... | @@ -711,8 +706,8 @@ describe("sortThreadsForSidebar", () => { | ... | @@ -711,8 +706,8 @@ describe("sortThreadsForSidebar", () => { |
| 711 | ); | 706 | ); |
| 712 | 707 | ||
| 713 | expect(sorted.map((thread) => thread.id)).toEqual([ | 708 | expect(sorted.map((thread) => thread.id)).toEqual([ |
| 714 | ThreadId.makeUnsafe("thread-2"), | 709 | ThreadId.make("thread-2"), |
| 715 | ThreadId.makeUnsafe("thread-1"), | 710 | ThreadId.make("thread-1"), |
| 716 | ]); | 711 | ]); |
| 717 | }); | 712 | }); |
| 718 | 713 | ||
| ... | @@ -720,7 +715,7 @@ describe("sortThreadsForSidebar", () => { | ... | @@ -720,7 +715,7 @@ describe("sortThreadsForSidebar", () => { |
| 720 | const sorted = sortThreadsForSidebar( | 715 | const sorted = sortThreadsForSidebar( |
| 721 | [ | 716 | [ |
| 722 | makeThread({ | 717 | makeThread({ |
| 723 | id: ThreadId.makeUnsafe("thread-1"), | 718 | id: ThreadId.make("thread-1"), |
| 724 | createdAt: "2026-03-09T10:00:00.000Z", | 719 | createdAt: "2026-03-09T10:00:00.000Z", |
| 725 | updatedAt: "2026-03-09T10:01:00.000Z", | 720 | updatedAt: "2026-03-09T10:01:00.000Z", |
| 726 | messages: [ | 721 | messages: [ |
| ... | @@ -735,7 +730,7 @@ describe("sortThreadsForSidebar", () => { | ... | @@ -735,7 +730,7 @@ describe("sortThreadsForSidebar", () => { |
| 735 | ], | 730 | ], |
| 736 | }), | 731 | }), |
| 737 | makeThread({ | 732 | makeThread({ |
| 738 | id: ThreadId.makeUnsafe("thread-2"), | 733 | id: ThreadId.make("thread-2"), |
| 739 | createdAt: "2026-03-09T10:05:00.000Z", | 734 | createdAt: "2026-03-09T10:05:00.000Z", |
| 740 | updatedAt: "2026-03-09T10:05:00.000Z", | 735 | updatedAt: "2026-03-09T10:05:00.000Z", |
| 741 | messages: [], | 736 | messages: [], |
| ... | @@ -745,8 +740,8 @@ describe("sortThreadsForSidebar", () => { | ... | @@ -745,8 +740,8 @@ describe("sortThreadsForSidebar", () => { |
| 745 | ); | 740 | ); |
| 746 | 741 | ||
| 747 | expect(sorted.map((thread) => thread.id)).toEqual([ | 742 | expect(sorted.map((thread) => thread.id)).toEqual([ |
| 748 | ThreadId.makeUnsafe("thread-2"), | 743 | ThreadId.make("thread-2"), |
| 749 | ThreadId.makeUnsafe("thread-1"), | 744 | ThreadId.make("thread-1"), |
| 750 | ]); | 745 | ]); |
| 751 | }); | 746 | }); |
| 752 | 747 | ||
| ... | @@ -754,13 +749,13 @@ describe("sortThreadsForSidebar", () => { | ... | @@ -754,13 +749,13 @@ describe("sortThreadsForSidebar", () => { |
| 754 | const sorted = sortThreadsForSidebar( | 749 | const sorted = sortThreadsForSidebar( |
| 755 | [ | 750 | [ |
| 756 | makeThread({ | 751 | makeThread({ |
| 757 | id: ThreadId.makeUnsafe("thread-1"), | 752 | id: ThreadId.make("thread-1"), |
| 758 | createdAt: "" as never, | 753 | createdAt: "" as never, |
| 759 | updatedAt: undefined, | 754 | updatedAt: undefined, |
| 760 | messages: [], | 755 | messages: [], |
| 761 | }), | 756 | }), |
| 762 | makeThread({ | 757 | makeThread({ |
| 763 | id: ThreadId.makeUnsafe("thread-2"), | 758 | id: ThreadId.make("thread-2"), |
| 764 | createdAt: "" as never, | 759 | createdAt: "" as never, |
| 765 | updatedAt: undefined, | 760 | updatedAt: undefined, |
| 766 | messages: [], | 761 | messages: [], |
| ... | @@ -770,8 +765,8 @@ describe("sortThreadsForSidebar", () => { | ... | @@ -770,8 +765,8 @@ describe("sortThreadsForSidebar", () => { |
| 770 | ); | 765 | ); |
| 771 | 766 | ||
| 772 | expect(sorted.map((thread) => thread.id)).toEqual([ | 767 | expect(sorted.map((thread) => thread.id)).toEqual([ |
| 773 | ThreadId.makeUnsafe("thread-2"), | 768 | ThreadId.make("thread-2"), |
| 774 | ThreadId.makeUnsafe("thread-1"), | 769 | ThreadId.make("thread-1"), |
| 775 | ]); | 770 | ]); |
| 776 | }); | 771 | }); |
| 777 | 772 | ||
| ... | @@ -779,12 +774,12 @@ describe("sortThreadsForSidebar", () => { | ... | @@ -779,12 +774,12 @@ describe("sortThreadsForSidebar", () => { |
| 779 | const sorted = sortThreadsForSidebar( | 774 | const sorted = sortThreadsForSidebar( |
| 780 | [ | 775 | [ |
| 781 | makeThread({ | 776 | makeThread({ |
| 782 | id: ThreadId.makeUnsafe("thread-1"), | 777 | id: ThreadId.make("thread-1"), |
| 783 | createdAt: "2026-03-09T10:05:00.000Z", | 778 | createdAt: "2026-03-09T10:05:00.000Z", |
| 784 | updatedAt: "2026-03-09T10:05:00.000Z", | 779 | updatedAt: "2026-03-09T10:05:00.000Z", |
| 785 | }), | 780 | }), |
| 786 | makeThread({ | 781 | makeThread({ |
| 787 | id: ThreadId.makeUnsafe("thread-2"), | 782 | id: ThreadId.make("thread-2"), |
| 788 | createdAt: "2026-03-09T10:00:00.000Z", | 783 | createdAt: "2026-03-09T10:00:00.000Z", |
| 789 | updatedAt: "2026-03-09T10:10:00.000Z", | 784 | updatedAt: "2026-03-09T10:10:00.000Z", |
| 790 | }), | 785 | }), |
| ... | @@ -793,8 +788,8 @@ describe("sortThreadsForSidebar", () => { | ... | @@ -793,8 +788,8 @@ describe("sortThreadsForSidebar", () => { |
| 793 | ); | 788 | ); |
| 794 | 789 | ||
| 795 | expect(sorted.map((thread) => thread.id)).toEqual([ | 790 | expect(sorted.map((thread) => thread.id)).toEqual([ |
| 796 | ThreadId.makeUnsafe("thread-1"), | 791 | ThreadId.make("thread-1"), |
| 797 | ThreadId.makeUnsafe("thread-2"), | 792 | ThreadId.make("thread-2"), |
| 798 | ]); | 793 | ]); |
| 799 | }); | 794 | }); |
| 800 | }); | 795 | }); |
| ... | @@ -804,80 +799,77 @@ describe("getFallbackThreadIdAfterDelete", () => { | ... | @@ -804,80 +799,77 @@ describe("getFallbackThreadIdAfterDelete", () => { |
| 804 | const fallbackThreadId = getFallbackThreadIdAfterDelete({ | 799 | const fallbackThreadId = getFallbackThreadIdAfterDelete({ |
| 805 | threads: [ | 800 | threads: [ |
| 806 | makeThread({ | 801 | makeThread({ |
| 807 | id: ThreadId.makeUnsafe("thread-oldest"), | 802 | id: ThreadId.make("thread-oldest"), |
| 808 | projectId: ProjectId.makeUnsafe("project-1"), | 803 | projectId: ProjectId.make("project-1"), |
| 809 | createdAt: "2026-03-09T10:00:00.000Z", | 804 | createdAt: "2026-03-09T10:00:00.000Z", |
| 810 | messages: [], | 805 | messages: [], |
| 811 | }), | 806 | }), |
| 812 | makeThread({ | 807 | makeThread({ |
| 813 | id: ThreadId.makeUnsafe("thread-active"), | 808 | id: ThreadId.make("thread-active"), |
| 814 | projectId: ProjectId.makeUnsafe("project-1"), | 809 | projectId: ProjectId.make("project-1"), |
| 815 | createdAt: "2026-03-09T10:05:00.000Z", | 810 | createdAt: "2026-03-09T10:05:00.000Z", |
| 816 | messages: [], | 811 | messages: [], |
| 817 | }), | 812 | }), |
| 818 | makeThread({ | 813 | makeThread({ |
| 819 | id: ThreadId.makeUnsafe("thread-newest"), | 814 | id: ThreadId.make("thread-newest"), |
| 820 | projectId: ProjectId.makeUnsafe("project-1"), | 815 | projectId: ProjectId.make("project-1"), |
| 821 | createdAt: "2026-03-09T10:10:00.000Z", | 816 | createdAt: "2026-03-09T10:10:00.000Z", |
| 822 | messages: [], | 817 | messages: [], |
| 823 | }), | 818 | }), |
| 824 | makeThread({ | 819 | makeThread({ |
| 825 | id: ThreadId.makeUnsafe("thread-other-project"), | 820 | id: ThreadId.make("thread-other-project"), |
| 826 | projectId: ProjectId.makeUnsafe("project-2"), | 821 | projectId: ProjectId.make("project-2"), |
| 827 | createdAt: "2026-03-09T10:20:00.000Z", | 822 | createdAt: "2026-03-09T10:20:00.000Z", |
| 828 | messages: [], | 823 | messages: [], |
| 829 | }), | 824 | }), |
| 830 | ], | 825 | ], |
| 831 | deletedThreadId: ThreadId.makeUnsafe("thread-active"), | 826 | deletedThreadId: ThreadId.make("thread-active"), |
| 832 | sortOrder: "created_at", | 827 | sortOrder: "created_at", |
| 833 | }); | 828 | }); |
| 834 | 829 | ||
| 835 | expect(fallbackThreadId).toBe(ThreadId.makeUnsafe("thread-newest")); | 830 | expect(fallbackThreadId).toBe(ThreadId.make("thread-newest")); |
| 836 | }); | 831 | }); |
| 837 | 832 | ||
| 838 | it("skips other threads being deleted in the same action", () => { | 833 | it("skips other threads being deleted in the same action", () => { |
| 839 | const fallbackThreadId = getFallbackThreadIdAfterDelete({ | 834 | const fallbackThreadId = getFallbackThreadIdAfterDelete({ |
| 840 | threads: [ | 835 | threads: [ |
| 841 | makeThread({ | 836 | makeThread({ |
| 842 | id: ThreadId.makeUnsafe("thread-active"), | 837 | id: ThreadId.make("thread-active"), |
| 843 | projectId: ProjectId.makeUnsafe("project-1"), | 838 | projectId: ProjectId.make("project-1"), |
| 844 | createdAt: "2026-03-09T10:05:00.000Z", | 839 | createdAt: "2026-03-09T10:05:00.000Z", |
| 845 | messages: [], | 840 | messages: [], |
| 846 | }), | 841 | }), |
| 847 | makeThread({ | 842 | makeThread({ |
| 848 | id: ThreadId.makeUnsafe("thread-newest"), | 843 | id: ThreadId.make("thread-newest"), |
| 849 | projectId: ProjectId.makeUnsafe("project-1"), | 844 | projectId: ProjectId.make("project-1"), |
| 850 | createdAt: "2026-03-09T10:10:00.000Z", | 845 | createdAt: "2026-03-09T10:10:00.000Z", |
| 851 | messages: [], | 846 | messages: [], |
| 852 | }), | 847 | }), |
| 853 | makeThread({ | 848 | makeThread({ |
| 854 | id: ThreadId.makeUnsafe("thread-next"), | 849 | id: ThreadId.make("thread-next"), |
| 855 | projectId: ProjectId.makeUnsafe("project-1"), | 850 | projectId: ProjectId.make("project-1"), |
| 856 | createdAt: "2026-03-09T10:07:00.000Z", | 851 | createdAt: "2026-03-09T10:07:00.000Z", |
| 857 | messages: [], | 852 | messages: [], |
| 858 | }), | 853 | }), |
| 859 | ], | 854 | ], |
| 860 | deletedThreadId: ThreadId.makeUnsafe("thread-active"), | 855 | deletedThreadId: ThreadId.make("thread-active"), |
| 861 | deletedThreadIds: new Set([ | 856 | deletedThreadIds: new Set([ThreadId.make("thread-active"), ThreadId.make("thread-newest")]), |
| 862 | ThreadId.makeUnsafe("thread-active"), | ||
| 863 | ThreadId.makeUnsafe("thread-newest"), | ||
| 864 | ]), | ||
| 865 | sortOrder: "created_at", | 857 | sortOrder: "created_at", |
| 866 | }); | 858 | }); |
| 867 | 859 | ||
| 868 | expect(fallbackThreadId).toBe(ThreadId.makeUnsafe("thread-next")); | 860 | expect(fallbackThreadId).toBe(ThreadId.make("thread-next")); |
| 869 | }); | 861 | }); |
| 870 | }); | 862 | }); |
| 871 | 863 | ||
| 872 | describe("sortProjectsForSidebar", () => { | 864 | describe("sortProjectsForSidebar", () => { |
| 873 | it("sorts projects by the most recent user message across their threads", () => { | 865 | it("sorts projects by the most recent user message across their threads", () => { |
| 874 | const projects = [ | 866 | const projects = [ |
| 875 | makeProject({ id: ProjectId.makeUnsafe("project-1"), name: "Older project" }), | 867 | makeProject({ id: ProjectId.make("project-1"), name: "Older project" }), |
| 876 | makeProject({ id: ProjectId.makeUnsafe("project-2"), name: "Newer project" }), | 868 | makeProject({ id: ProjectId.make("project-2"), name: "Newer project" }), |
| 877 | ]; | 869 | ]; |
| 878 | const threads = [ | 870 | const threads = [ |
| 879 | makeThread({ | 871 | makeThread({ |
| 880 | projectId: ProjectId.makeUnsafe("project-1"), | 872 | projectId: ProjectId.make("project-1"), |
| 881 | updatedAt: "2026-03-09T10:20:00.000Z", | 873 | updatedAt: "2026-03-09T10:20:00.000Z", |
| 882 | messages: [ | 874 | messages: [ |
| 883 | { | 875 | { |
| ... | @@ -891,8 +883,8 @@ describe("sortProjectsForSidebar", () => { | ... | @@ -891,8 +883,8 @@ describe("sortProjectsForSidebar", () => { |
| 891 | ], | 883 | ], |
| 892 | }), | 884 | }), |
| 893 | makeThread({ | 885 | makeThread({ |
| 894 | id: ThreadId.makeUnsafe("thread-2"), | 886 | id: ThreadId.make("thread-2"), |
| 895 | projectId: ProjectId.makeUnsafe("project-2"), | 887 | projectId: ProjectId.make("project-2"), |
| 896 | updatedAt: "2026-03-09T10:05:00.000Z", | 888 | updatedAt: "2026-03-09T10:05:00.000Z", |
| 897 | messages: [ | 889 | messages: [ |
| 898 | { | 890 | { |
| ... | @@ -910,8 +902,8 @@ describe("sortProjectsForSidebar", () => { | ... | @@ -910,8 +902,8 @@ describe("sortProjectsForSidebar", () => { |
| 910 | const sorted = sortProjectsForSidebar(projects, threads, "updated_at"); | 902 | const sorted = sortProjectsForSidebar(projects, threads, "updated_at"); |
| 911 | 903 | ||
| 912 | expect(sorted.map((project) => project.id)).toEqual([ | 904 | expect(sorted.map((project) => project.id)).toEqual([ |
| 913 | ProjectId.makeUnsafe("project-2"), | 905 | ProjectId.make("project-2"), |
| 914 | ProjectId.makeUnsafe("project-1"), | 906 | ProjectId.make("project-1"), |
| 915 | ]); | 907 | ]); |
| 916 | }); | 908 | }); |
| 917 | 909 | ||
| ... | @@ -919,12 +911,12 @@ describe("sortProjectsForSidebar", () => { | ... | @@ -919,12 +911,12 @@ describe("sortProjectsForSidebar", () => { |
| 919 | const sorted = sortProjectsForSidebar( | 911 | const sorted = sortProjectsForSidebar( |
| 920 | [ | 912 | [ |
| 921 | makeProject({ | 913 | makeProject({ |
| 922 | id: ProjectId.makeUnsafe("project-1"), | 914 | id: ProjectId.make("project-1"), |
| 923 | name: "Older project", | 915 | name: "Older project", |
| 924 | updatedAt: "2026-03-09T10:01:00.000Z", | 916 | updatedAt: "2026-03-09T10:01:00.000Z", |
| 925 | }), | 917 | }), |
| 926 | makeProject({ | 918 | makeProject({ |
| 927 | id: ProjectId.makeUnsafe("project-2"), | 919 | id: ProjectId.make("project-2"), |
| 928 | name: "Newer project", | 920 | name: "Newer project", |
| 929 | updatedAt: "2026-03-09T10:05:00.000Z", | 921 | updatedAt: "2026-03-09T10:05:00.000Z", |
| 930 | }), | 922 | }), |
| ... | @@ -934,8 +926,8 @@ describe("sortProjectsForSidebar", () => { | ... | @@ -934,8 +926,8 @@ describe("sortProjectsForSidebar", () => { |
| 934 | ); | 926 | ); |
| 935 | 927 | ||
| 936 | expect(sorted.map((project) => project.id)).toEqual([ | 928 | expect(sorted.map((project) => project.id)).toEqual([ |
| 937 | ProjectId.makeUnsafe("project-2"), | 929 | ProjectId.make("project-2"), |
| 938 | ProjectId.makeUnsafe("project-1"), | 930 | ProjectId.make("project-1"), |
| 939 | ]); | 931 | ]); |
| 940 | }); | 932 | }); |
| 941 | 933 | ||
| ... | @@ -943,13 +935,13 @@ describe("sortProjectsForSidebar", () => { | ... | @@ -943,13 +935,13 @@ describe("sortProjectsForSidebar", () => { |
| 943 | const sorted = sortProjectsForSidebar( | 935 | const sorted = sortProjectsForSidebar( |
| 944 | [ | 936 | [ |
| 945 | makeProject({ | 937 | makeProject({ |
| 946 | id: ProjectId.makeUnsafe("project-2"), | 938 | id: ProjectId.make("project-2"), |
| 947 | name: "Beta", | 939 | name: "Beta", |
| 948 | createdAt: undefined, | 940 | createdAt: undefined, |
| 949 | updatedAt: undefined, | 941 | updatedAt: undefined, |
| 950 | }), | 942 | }), |
| 951 | makeProject({ | 943 | makeProject({ |
| 952 | id: ProjectId.makeUnsafe("project-1"), | 944 | id: ProjectId.make("project-1"), |
| 953 | name: "Alpha", | 945 | name: "Alpha", |
| 954 | createdAt: undefined, | 946 | createdAt: undefined, |
| 955 | updatedAt: undefined, | 947 | updatedAt: undefined, |
| ... | @@ -960,22 +952,22 @@ describe("sortProjectsForSidebar", () => { | ... | @@ -960,22 +952,22 @@ describe("sortProjectsForSidebar", () => { |
| 960 | ); | 952 | ); |
| 961 | 953 | ||
| 962 | expect(sorted.map((project) => project.id)).toEqual([ | 954 | expect(sorted.map((project) => project.id)).toEqual([ |
| 963 | ProjectId.makeUnsafe("project-1"), | 955 | ProjectId.make("project-1"), |
| 964 | ProjectId.makeUnsafe("project-2"), | 956 | ProjectId.make("project-2"), |
| 965 | ]); | 957 | ]); |
| 966 | }); | 958 | }); |
| 967 | 959 | ||
| 968 | it("preserves manual project ordering", () => { | 960 | it("preserves manual project ordering", () => { |
| 969 | const projects = [ | 961 | const projects = [ |
| 970 | makeProject({ id: ProjectId.makeUnsafe("project-2"), name: "Second" }), | 962 | makeProject({ id: ProjectId.make("project-2"), name: "Second" }), |
| 971 | makeProject({ id: ProjectId.makeUnsafe("project-1"), name: "First" }), | 963 | makeProject({ id: ProjectId.make("project-1"), name: "First" }), |
| 972 | ]; | 964 | ]; |
| 973 | 965 | ||
| 974 | const sorted = sortProjectsForSidebar(projects, [], "manual"); | 966 | const sorted = sortProjectsForSidebar(projects, [], "manual"); |
| 975 | 967 | ||
| 976 | expect(sorted.map((project) => project.id)).toEqual([ | 968 | expect(sorted.map((project) => project.id)).toEqual([ |
| 977 | ProjectId.makeUnsafe("project-2"), | 969 | ProjectId.make("project-2"), |
| 978 | ProjectId.makeUnsafe("project-1"), | 970 | ProjectId.make("project-1"), |
| 979 | ]); | 971 | ]); |
| 980 | }); | 972 | }); |
| 981 | 973 | ||
| ... | @@ -983,26 +975,26 @@ describe("sortProjectsForSidebar", () => { | ... | @@ -983,26 +975,26 @@ describe("sortProjectsForSidebar", () => { |
| 983 | const sorted = sortProjectsForSidebar( | 975 | const sorted = sortProjectsForSidebar( |
| 984 | [ | 976 | [ |
| 985 | makeProject({ | 977 | makeProject({ |
| 986 | id: ProjectId.makeUnsafe("project-1"), | 978 | id: ProjectId.make("project-1"), |
| 987 | name: "Visible project", | 979 | name: "Visible project", |
| 988 | updatedAt: "2026-03-09T10:01:00.000Z", | 980 | updatedAt: "2026-03-09T10:01:00.000Z", |
| 989 | }), | 981 | }), |
| 990 | makeProject({ | 982 | makeProject({ |
| 991 | id: ProjectId.makeUnsafe("project-2"), | 983 | id: ProjectId.make("project-2"), |
| 992 | name: "Archived-only project", | 984 | name: "Archived-only project", |
| 993 | updatedAt: "2026-03-09T10:00:00.000Z", | 985 | updatedAt: "2026-03-09T10:00:00.000Z", |
| 994 | }), | 986 | }), |
| 995 | ], | 987 | ], |
| 996 | [ | 988 | [ |
| 997 | makeThread({ | 989 | makeThread({ |
| 998 | id: ThreadId.makeUnsafe("thread-visible"), | 990 | id: ThreadId.make("thread-visible"), |
| 999 | projectId: ProjectId.makeUnsafe("project-1"), | 991 | projectId: ProjectId.make("project-1"), |
| 1000 | updatedAt: "2026-03-09T10:02:00.000Z", | 992 | updatedAt: "2026-03-09T10:02:00.000Z", |
| 1001 | archivedAt: null, | 993 | archivedAt: null, |
| 1002 | }), | 994 | }), |
| 1003 | makeThread({ | 995 | makeThread({ |
| 1004 | id: ThreadId.makeUnsafe("thread-archived"), | 996 | id: ThreadId.make("thread-archived"), |
| 1005 | projectId: ProjectId.makeUnsafe("project-2"), | 997 | projectId: ProjectId.make("project-2"), |
| 1006 | updatedAt: "2026-03-09T10:10:00.000Z", | 998 | updatedAt: "2026-03-09T10:10:00.000Z", |
| 1007 | archivedAt: "2026-03-09T10:11:00.000Z", | 999 | archivedAt: "2026-03-09T10:11:00.000Z", |
| 1008 | }), | 1000 | }), |
| ... | @@ -1011,8 +1003,8 @@ describe("sortProjectsForSidebar", () => { | ... | @@ -1011,8 +1003,8 @@ describe("sortProjectsForSidebar", () => { |
| 1011 | ); | 1003 | ); |
| 1012 | 1004 | ||
| 1013 | expect(sorted.map((project) => project.id)).toEqual([ | 1005 | expect(sorted.map((project) => project.id)).toEqual([ |
| 1014 | ProjectId.makeUnsafe("project-1"), | 1006 | ProjectId.make("project-1"), |
| 1015 | ProjectId.makeUnsafe("project-2"), | 1007 | ProjectId.make("project-2"), |
| 1016 | ]); | 1008 | ]); |
| 1017 | }); | 1009 | }); |
| 1018 | 1010 |
apps/web/src/components/ThreadTerminalDrawer.browser.tsx+1-1| ... | @@ -121,7 +121,7 @@ vi.mock("~/localApi", () => ({ | ... | @@ -121,7 +121,7 @@ vi.mock("~/localApi", () => ({ |
| 121 | 121 | ||
| 122 | import { TerminalViewport } from "./ThreadTerminalDrawer"; | 122 | import { TerminalViewport } from "./ThreadTerminalDrawer"; |
| 123 | 123 | ||
| 124 | const THREAD_ID = ThreadId.makeUnsafe("thread-terminal-browser"); | 124 | const THREAD_ID = ThreadId.make("thread-terminal-browser"); |
| 125 | 125 | ||
| 126 | function createEnvironmentApi() { | 126 | function createEnvironmentApi() { |
| 127 | return { | 127 | return { |
apps/web/src/components/chat/ChangedFilesTree.test.tsx+2-2| ... | @@ -39,7 +39,7 @@ describe("ChangedFilesTree", () => { | ... | @@ -39,7 +39,7 @@ describe("ChangedFilesTree", () => { |
| 39 | ({ files, visibleLabels, hiddenLabels }) => { | 39 | ({ files, visibleLabels, hiddenLabels }) => { |
| 40 | const markup = renderToStaticMarkup( | 40 | const markup = renderToStaticMarkup( |
| 41 | <ChangedFilesTree | 41 | <ChangedFilesTree |
| 42 | turnId={TurnId.makeUnsafe("turn-1")} | 42 | turnId={TurnId.make("turn-1")} |
| 43 | files={files} | 43 | files={files} |
| 44 | allDirectoriesExpanded={false} | 44 | allDirectoriesExpanded={false} |
| 45 | resolvedTheme="light" | 45 | resolvedTheme="light" |
| ... | @@ -100,7 +100,7 @@ describe("ChangedFilesTree", () => { | ... | @@ -100,7 +100,7 @@ describe("ChangedFilesTree", () => { |
| 100 | ({ files, visibleLabels }) => { | 100 | ({ files, visibleLabels }) => { |
| 101 | const markup = renderToStaticMarkup( | 101 | const markup = renderToStaticMarkup( |
| 102 | <ChangedFilesTree | 102 | <ChangedFilesTree |
| 103 | turnId={TurnId.makeUnsafe("turn-1")} | 103 | turnId={TurnId.make("turn-1")} |
| 104 | files={files} | 104 | files={files} |
| 105 | allDirectoriesExpanded | 105 | allDirectoriesExpanded |
| 106 | resolvedTheme="light" | 106 | resolvedTheme="light" |
apps/web/src/components/chat/CompactComposerControlsMenu.browser.tsx+2-2| ... | @@ -15,10 +15,10 @@ import { CompactComposerControlsMenu } from "./CompactComposerControlsMenu"; | ... | @@ -15,10 +15,10 @@ import { CompactComposerControlsMenu } from "./CompactComposerControlsMenu"; |
| 15 | import { TraitsMenuContent } from "./TraitsPicker"; | 15 | import { TraitsMenuContent } from "./TraitsPicker"; |
| 16 | import { useComposerDraftStore } from "../../composerDraftStore"; | 16 | import { useComposerDraftStore } from "../../composerDraftStore"; |
| 17 | 17 | ||
| 18 | const LOCAL_ENVIRONMENT_ID = EnvironmentId.makeUnsafe("environment-local"); | 18 | const LOCAL_ENVIRONMENT_ID = EnvironmentId.make("environment-local"); |
| 19 | 19 | ||
| 20 | async function mountMenu(props?: { modelSelection?: ModelSelection; prompt?: string }) { | 20 | async function mountMenu(props?: { modelSelection?: ModelSelection; prompt?: string }) { |
| 21 | const threadId = ThreadId.makeUnsafe("thread-compact-menu"); | 21 | const threadId = ThreadId.make("thread-compact-menu"); |
| 22 | const threadRef = scopeThreadRef(LOCAL_ENVIRONMENT_ID, threadId); | 22 | const threadRef = scopeThreadRef(LOCAL_ENVIRONMENT_ID, threadId); |
| 23 | const threadKey = scopedThreadKey(threadRef); | 23 | const threadKey = scopedThreadKey(threadRef); |
| 24 | const provider = props?.modelSelection?.provider ?? "claudeAgent"; | 24 | const provider = props?.modelSelection?.provider ?? "claudeAgent"; |
apps/web/src/components/chat/ComposerPendingTerminalContexts.test.tsx+1-1| ... | @@ -10,7 +10,7 @@ describe("ComposerPendingTerminalContextChip", () => { | ... | @@ -10,7 +10,7 @@ describe("ComposerPendingTerminalContextChip", () => { |
| 10 | <ComposerPendingTerminalContextChip | 10 | <ComposerPendingTerminalContextChip |
| 11 | context={{ | 11 | context={{ |
| 12 | id: "ctx-expired", | 12 | id: "ctx-expired", |
| 13 | threadId: ThreadId.makeUnsafe("thread-1"), | 13 | threadId: ThreadId.make("thread-1"), |
| 14 | terminalId: "default", | 14 | terminalId: "default", |
| 15 | terminalLabel: "Terminal 1", | 15 | terminalLabel: "Terminal 1", |
| 16 | lineStart: 2, | 16 | lineStart: 2, |
apps/web/src/components/chat/MessagesTimeline.test.tsx+1-1| ... | @@ -60,7 +60,7 @@ describe("MessagesTimeline", () => { | ... | @@ -60,7 +60,7 @@ describe("MessagesTimeline", () => { |
| 60 | kind: "message", | 60 | kind: "message", |
| 61 | createdAt: "2026-03-17T19:12:28.000Z", | 61 | createdAt: "2026-03-17T19:12:28.000Z", |
| 62 | message: { | 62 | message: { |
| 63 | id: MessageId.makeUnsafe("message-2"), | 63 | id: MessageId.make("message-2"), |
| 64 | role: "user", | 64 | role: "user", |
| 65 | text: [ | 65 | text: [ |
| 66 | "yoo what's @terminal-1:1-5 mean", | 66 | "yoo what's @terminal-1:1-5 mean", |
apps/web/src/components/chat/MessagesTimeline.virtualization.browser.tsx+1-1| ... | @@ -101,7 +101,7 @@ function createMessage(input: { | ... | @@ -101,7 +101,7 @@ function createMessage(input: { |
| 101 | attachments?: ChatMessage["attachments"]; | 101 | attachments?: ChatMessage["attachments"]; |
| 102 | }): ChatMessage { | 102 | }): ChatMessage { |
| 103 | return { | 103 | return { |
| 104 | id: MessageId.makeUnsafe(input.id), | 104 | id: MessageId.make(input.id), |
| 105 | role: input.role, | 105 | role: input.role, |
| 106 | text: input.text, | 106 | text: input.text, |
| 107 | ...(input.attachments ? { attachments: input.attachments } : {}), | 107 | ...(input.attachments ? { attachments: input.attachments } : {}), |
apps/web/src/components/chat/TraitsPicker.browser.tsx+3-3| ... | @@ -28,11 +28,11 @@ import { DEFAULT_CLIENT_SETTINGS } from "@t3tools/contracts/settings"; | ... | @@ -28,11 +28,11 @@ import { DEFAULT_CLIENT_SETTINGS } from "@t3tools/contracts/settings"; |
| 28 | 28 | ||
| 29 | // ── Claude TraitsPicker tests ───────────────────────────────────────── | 29 | // ── Claude TraitsPicker tests ───────────────────────────────────────── |
| 30 | 30 | ||
| 31 | const LOCAL_ENVIRONMENT_ID = EnvironmentId.makeUnsafe("environment-local"); | 31 | const LOCAL_ENVIRONMENT_ID = EnvironmentId.make("environment-local"); |
| 32 | const CLAUDE_THREAD_ID = ThreadId.makeUnsafe("thread-claude-traits"); | 32 | const CLAUDE_THREAD_ID = ThreadId.make("thread-claude-traits"); |
| 33 | const CLAUDE_THREAD_REF = scopeThreadRef(LOCAL_ENVIRONMENT_ID, CLAUDE_THREAD_ID); | 33 | const CLAUDE_THREAD_REF = scopeThreadRef(LOCAL_ENVIRONMENT_ID, CLAUDE_THREAD_ID); |
| 34 | const CLAUDE_THREAD_KEY = scopedThreadKey(CLAUDE_THREAD_REF); | 34 | const CLAUDE_THREAD_KEY = scopedThreadKey(CLAUDE_THREAD_REF); |
| 35 | const CODEX_THREAD_ID = ThreadId.makeUnsafe("thread-codex-traits"); | 35 | const CODEX_THREAD_ID = ThreadId.make("thread-codex-traits"); |
| 36 | const CODEX_THREAD_REF = scopeThreadRef(LOCAL_ENVIRONMENT_ID, CODEX_THREAD_ID); | 36 | const CODEX_THREAD_REF = scopeThreadRef(LOCAL_ENVIRONMENT_ID, CODEX_THREAD_ID); |
| 37 | const CODEX_THREAD_KEY = scopedThreadKey(CODEX_THREAD_REF); | 37 | const CODEX_THREAD_KEY = scopedThreadKey(CODEX_THREAD_REF); |
| 38 | const TEST_PROVIDERS: ReadonlyArray<ServerProvider> = [ | 38 | const TEST_PROVIDERS: ReadonlyArray<ServerProvider> = [ |
apps/web/src/components/settings/SettingsPanels.browser.tsx+5-5| ... | @@ -92,7 +92,7 @@ const authAccessHarness = vi.hoisted(() => { | ... | @@ -92,7 +92,7 @@ const authAccessHarness = vi.hoisted(() => { |
| 92 | revision, | 92 | revision, |
| 93 | type: "clientRemoved", | 93 | type: "clientRemoved", |
| 94 | payload: { | 94 | payload: { |
| 95 | sessionId: AuthSessionId.makeUnsafe(sessionId), | 95 | sessionId: AuthSessionId.make(sessionId), |
| 96 | }, | 96 | }, |
| 97 | }); | 97 | }); |
| 98 | revision += 1; | 98 | revision += 1; |
| ... | @@ -119,13 +119,13 @@ vi.mock("../../environments/runtime", () => { | ... | @@ -119,13 +119,13 @@ vi.mock("../../environments/runtime", () => { |
| 119 | id: "environment-local", | 119 | id: "environment-local", |
| 120 | label: "Local environment", | 120 | label: "Local environment", |
| 121 | source: "manual" as const, | 121 | source: "manual" as const, |
| 122 | environmentId: EnvironmentId.makeUnsafe("environment-local"), | 122 | environmentId: EnvironmentId.make("environment-local"), |
| 123 | target: { | 123 | target: { |
| 124 | httpBaseUrl: "http://localhost:3000", | 124 | httpBaseUrl: "http://localhost:3000", |
| 125 | wsBaseUrl: "ws://localhost:3000", | 125 | wsBaseUrl: "ws://localhost:3000", |
| 126 | }, | 126 | }, |
| 127 | }, | 127 | }, |
| 128 | environmentId: EnvironmentId.makeUnsafe("environment-local"), | 128 | environmentId: EnvironmentId.make("environment-local"), |
| 129 | client: { | 129 | client: { |
| 130 | server: { | 130 | server: { |
| 131 | subscribeAuthAccess: (listener: Parameters<typeof authAccessHarness.subscribe>[0]) => | 131 | subscribeAuthAccess: (listener: Parameters<typeof authAccessHarness.subscribe>[0]) => |
| ... | @@ -171,7 +171,7 @@ vi.mock("../../environments/runtime", () => { | ... | @@ -171,7 +171,7 @@ vi.mock("../../environments/runtime", () => { |
| 171 | function createBaseServerConfig(): ServerConfig { | 171 | function createBaseServerConfig(): ServerConfig { |
| 172 | return { | 172 | return { |
| 173 | environment: { | 173 | environment: { |
| 174 | environmentId: EnvironmentId.makeUnsafe("environment-local"), | 174 | environmentId: EnvironmentId.make("environment-local"), |
| 175 | label: "Local environment", | 175 | label: "Local environment", |
| 176 | platform: { os: "darwin" as const, arch: "arm64" as const }, | 176 | platform: { os: "darwin" as const, arch: "arm64" as const }, |
| 177 | serverVersion: "0.0.0-test", | 177 | serverVersion: "0.0.0-test", |
| ... | @@ -245,7 +245,7 @@ function makeClientSession(input: { | ... | @@ -245,7 +245,7 @@ function makeClientSession(input: { |
| 245 | deviceType: "unknown", | 245 | deviceType: "unknown", |
| 246 | ...input.client, | 246 | ...input.client, |
| 247 | }, | 247 | }, |
| 248 | sessionId: AuthSessionId.makeUnsafe(input.sessionId), | 248 | sessionId: AuthSessionId.make(input.sessionId), |
| 249 | issuedAt: makeUtc(input.issuedAt), | 249 | issuedAt: makeUtc(input.issuedAt), |
| 250 | expiresAt: makeUtc(input.expiresAt), | 250 | expiresAt: makeUtc(input.expiresAt), |
| 251 | lastConnectedAt: | 251 | lastConnectedAt: |
apps/web/src/composerDraftStore.test.ts+22-22| ... | @@ -70,7 +70,7 @@ function makeTerminalContext(input: { | ... | @@ -70,7 +70,7 @@ function makeTerminalContext(input: { |
| 70 | }): TerminalContextDraft { | 70 | }): TerminalContextDraft { |
| 71 | return { | 71 | return { |
| 72 | id: input.id, | 72 | id: input.id, |
| 73 | threadId: ThreadId.makeUnsafe("thread-dedupe"), | 73 | threadId: ThreadId.make("thread-dedupe"), |
| 74 | terminalId: input.terminalId ?? "default", | 74 | terminalId: input.terminalId ?? "default", |
| 75 | terminalLabel: input.terminalLabel ?? "Terminal 1", | 75 | terminalLabel: input.terminalLabel ?? "Terminal 1", |
| 76 | lineStart: input.lineStart ?? 4, | 76 | lineStart: input.lineStart ?? 4, |
| ... | @@ -106,9 +106,9 @@ function providerModelOptions(options: ProviderModelOptions): ProviderModelOptio | ... | @@ -106,9 +106,9 @@ function providerModelOptions(options: ProviderModelOptions): ProviderModelOptio |
| 106 | return options; | 106 | return options; |
| 107 | } | 107 | } |
| 108 | 108 | ||
| 109 | const TEST_ENVIRONMENT_ID = EnvironmentId.makeUnsafe("environment-local"); | 109 | const TEST_ENVIRONMENT_ID = EnvironmentId.make("environment-local"); |
| 110 | const OTHER_TEST_ENVIRONMENT_ID = EnvironmentId.makeUnsafe("environment-remote"); | 110 | const OTHER_TEST_ENVIRONMENT_ID = EnvironmentId.make("environment-remote"); |
| 111 | const LEGACY_TEST_ENVIRONMENT_ID = EnvironmentId.makeUnsafe("__legacy__"); | 111 | const LEGACY_TEST_ENVIRONMENT_ID = EnvironmentId.make("__legacy__"); |
| 112 | 112 | ||
| 113 | function threadKeyFor( | 113 | function threadKeyFor( |
| 114 | threadId: ThreadId, | 114 | threadId: ThreadId, |
| ... | @@ -130,7 +130,7 @@ function draftByKey(key: string) { | ... | @@ -130,7 +130,7 @@ function draftByKey(key: string) { |
| 130 | } | 130 | } |
| 131 | 131 | ||
| 132 | describe("composerDraftStore addImages", () => { | 132 | describe("composerDraftStore addImages", () => { |
| 133 | const threadId = ThreadId.makeUnsafe("thread-dedupe"); | 133 | const threadId = ThreadId.make("thread-dedupe"); |
| 134 | const threadRef = scopeThreadRef(TEST_ENVIRONMENT_ID, threadId); | 134 | const threadRef = scopeThreadRef(TEST_ENVIRONMENT_ID, threadId); |
| 135 | let originalRevokeObjectUrl: typeof URL.revokeObjectURL; | 135 | let originalRevokeObjectUrl: typeof URL.revokeObjectURL; |
| 136 | let revokeSpy: ReturnType<typeof vi.fn<(url: string) => void>>; | 136 | let revokeSpy: ReturnType<typeof vi.fn<(url: string) => void>>; |
| ... | @@ -216,7 +216,7 @@ describe("composerDraftStore addImages", () => { | ... | @@ -216,7 +216,7 @@ describe("composerDraftStore addImages", () => { |
| 216 | }); | 216 | }); |
| 217 | 217 | ||
| 218 | describe("composerDraftStore clearComposerContent", () => { | 218 | describe("composerDraftStore clearComposerContent", () => { |
| 219 | const threadId = ThreadId.makeUnsafe("thread-clear"); | 219 | const threadId = ThreadId.make("thread-clear"); |
| 220 | const threadRef = scopeThreadRef(TEST_ENVIRONMENT_ID, threadId); | 220 | const threadRef = scopeThreadRef(TEST_ENVIRONMENT_ID, threadId); |
| 221 | let originalRevokeObjectUrl: typeof URL.revokeObjectURL; | 221 | let originalRevokeObjectUrl: typeof URL.revokeObjectURL; |
| 222 | let revokeSpy: ReturnType<typeof vi.fn<(url: string) => void>>; | 222 | let revokeSpy: ReturnType<typeof vi.fn<(url: string) => void>>; |
| ... | @@ -248,7 +248,7 @@ describe("composerDraftStore clearComposerContent", () => { | ... | @@ -248,7 +248,7 @@ describe("composerDraftStore clearComposerContent", () => { |
| 248 | }); | 248 | }); |
| 249 | 249 | ||
| 250 | describe("composerDraftStore syncPersistedAttachments", () => { | 250 | describe("composerDraftStore syncPersistedAttachments", () => { |
| 251 | const threadId = ThreadId.makeUnsafe("thread-sync-persisted"); | 251 | const threadId = ThreadId.make("thread-sync-persisted"); |
| 252 | const threadRef = scopeThreadRef(TEST_ENVIRONMENT_ID, threadId); | 252 | const threadRef = scopeThreadRef(TEST_ENVIRONMENT_ID, threadId); |
| 253 | 253 | ||
| 254 | beforeEach(() => { | 254 | beforeEach(() => { |
| ... | @@ -304,7 +304,7 @@ describe("composerDraftStore syncPersistedAttachments", () => { | ... | @@ -304,7 +304,7 @@ describe("composerDraftStore syncPersistedAttachments", () => { |
| 304 | }); | 304 | }); |
| 305 | 305 | ||
| 306 | describe("composerDraftStore terminal contexts", () => { | 306 | describe("composerDraftStore terminal contexts", () => { |
| 307 | const threadId = ThreadId.makeUnsafe("thread-dedupe"); | 307 | const threadId = ThreadId.make("thread-dedupe"); |
| 308 | const threadRef = scopeThreadRef(TEST_ENVIRONMENT_ID, threadId); | 308 | const threadRef = scopeThreadRef(TEST_ENVIRONMENT_ID, threadId); |
| 309 | 309 | ||
| 310 | beforeEach(() => { | 310 | beforeEach(() => { |
| ... | @@ -482,18 +482,18 @@ describe("composerDraftStore terminal contexts", () => { | ... | @@ -482,18 +482,18 @@ describe("composerDraftStore terminal contexts", () => { |
| 482 | }); | 482 | }); |
| 483 | 483 | ||
| 484 | describe("composerDraftStore project draft thread mapping", () => { | 484 | describe("composerDraftStore project draft thread mapping", () => { |
| 485 | const projectId = ProjectId.makeUnsafe("project-a"); | 485 | const projectId = ProjectId.make("project-a"); |
| 486 | const otherProjectId = ProjectId.makeUnsafe("project-b"); | 486 | const otherProjectId = ProjectId.make("project-b"); |
| 487 | const projectRef = scopeProjectRef(TEST_ENVIRONMENT_ID, projectId); | 487 | const projectRef = scopeProjectRef(TEST_ENVIRONMENT_ID, projectId); |
| 488 | const otherProjectRef = scopeProjectRef(TEST_ENVIRONMENT_ID, otherProjectId); | 488 | const otherProjectRef = scopeProjectRef(TEST_ENVIRONMENT_ID, otherProjectId); |
| 489 | const remoteProjectRef = scopeProjectRef(OTHER_TEST_ENVIRONMENT_ID, projectId); | 489 | const remoteProjectRef = scopeProjectRef(OTHER_TEST_ENVIRONMENT_ID, projectId); |
| 490 | const threadId = ThreadId.makeUnsafe("thread-a"); | 490 | const threadId = ThreadId.make("thread-a"); |
| 491 | const otherThreadId = ThreadId.makeUnsafe("thread-b"); | 491 | const otherThreadId = ThreadId.make("thread-b"); |
| 492 | const draftId = DraftId.makeUnsafe("draft-a"); | 492 | const draftId = DraftId.make("draft-a"); |
| 493 | const otherDraftId = DraftId.makeUnsafe("draft-b"); | 493 | const otherDraftId = DraftId.make("draft-b"); |
| 494 | const sharedDraftId = DraftId.makeUnsafe("draft-shared"); | 494 | const sharedDraftId = DraftId.make("draft-shared"); |
| 495 | const localDraftId = DraftId.makeUnsafe("draft-local"); | 495 | const localDraftId = DraftId.make("draft-local"); |
| 496 | const remoteDraftId = DraftId.makeUnsafe("draft-remote"); | 496 | const remoteDraftId = DraftId.make("draft-remote"); |
| 497 | 497 | ||
| 498 | beforeEach(() => { | 498 | beforeEach(() => { |
| 499 | resetComposerDraftStore(); | 499 | resetComposerDraftStore(); |
| ... | @@ -847,7 +847,7 @@ describe("composerDraftStore project draft thread mapping", () => { | ... | @@ -847,7 +847,7 @@ describe("composerDraftStore project draft thread mapping", () => { |
| 847 | }); | 847 | }); |
| 848 | 848 | ||
| 849 | describe("composerDraftStore modelSelection", () => { | 849 | describe("composerDraftStore modelSelection", () => { |
| 850 | const threadId = ThreadId.makeUnsafe("thread-model-options"); | 850 | const threadId = ThreadId.make("thread-model-options"); |
| 851 | const threadRef = scopeThreadRef(TEST_ENVIRONMENT_ID, threadId); | 851 | const threadRef = scopeThreadRef(TEST_ENVIRONMENT_ID, threadId); |
| 852 | 852 | ||
| 853 | beforeEach(() => { | 853 | beforeEach(() => { |
| ... | @@ -1078,7 +1078,7 @@ describe("composerDraftStore modelSelection", () => { | ... | @@ -1078,7 +1078,7 @@ describe("composerDraftStore modelSelection", () => { |
| 1078 | }); | 1078 | }); |
| 1079 | 1079 | ||
| 1080 | describe("composerDraftStore setModelSelection", () => { | 1080 | describe("composerDraftStore setModelSelection", () => { |
| 1081 | const threadId = ThreadId.makeUnsafe("thread-model"); | 1081 | const threadId = ThreadId.make("thread-model"); |
| 1082 | const threadRef = scopeThreadRef(TEST_ENVIRONMENT_ID, threadId); | 1082 | const threadRef = scopeThreadRef(TEST_ENVIRONMENT_ID, threadId); |
| 1083 | 1083 | ||
| 1084 | beforeEach(() => { | 1084 | beforeEach(() => { |
| ... | @@ -1133,7 +1133,7 @@ describe("composerDraftStore sticky composer settings", () => { | ... | @@ -1133,7 +1133,7 @@ describe("composerDraftStore sticky composer settings", () => { |
| 1133 | 1133 | ||
| 1134 | it("applies sticky activeProvider to new drafts", () => { | 1134 | it("applies sticky activeProvider to new drafts", () => { |
| 1135 | const store = useComposerDraftStore.getState(); | 1135 | const store = useComposerDraftStore.getState(); |
| 1136 | const threadId = ThreadId.makeUnsafe("thread-sticky-active-provider"); | 1136 | const threadId = ThreadId.make("thread-sticky-active-provider"); |
| 1137 | const threadRef = scopeThreadRef(TEST_ENVIRONMENT_ID, threadId); | 1137 | const threadRef = scopeThreadRef(TEST_ENVIRONMENT_ID, threadId); |
| 1138 | 1138 | ||
| 1139 | store.setStickyModelSelection(modelSelection("claudeAgent", "claude-opus-4-6")); | 1139 | store.setStickyModelSelection(modelSelection("claudeAgent", "claude-opus-4-6")); |
| ... | @@ -1149,7 +1149,7 @@ describe("composerDraftStore sticky composer settings", () => { | ... | @@ -1149,7 +1149,7 @@ describe("composerDraftStore sticky composer settings", () => { |
| 1149 | }); | 1149 | }); |
| 1150 | 1150 | ||
| 1151 | describe("composerDraftStore provider-scoped option updates", () => { | 1151 | describe("composerDraftStore provider-scoped option updates", () => { |
| 1152 | const threadId = ThreadId.makeUnsafe("thread-provider"); | 1152 | const threadId = ThreadId.make("thread-provider"); |
| 1153 | const threadRef = scopeThreadRef(TEST_ENVIRONMENT_ID, threadId); | 1153 | const threadRef = scopeThreadRef(TEST_ENVIRONMENT_ID, threadId); |
| 1154 | 1154 | ||
| 1155 | beforeEach(() => { | 1155 | beforeEach(() => { |
| ... | @@ -1175,7 +1175,7 @@ describe("composerDraftStore provider-scoped option updates", () => { | ... | @@ -1175,7 +1175,7 @@ describe("composerDraftStore provider-scoped option updates", () => { |
| 1175 | }); | 1175 | }); |
| 1176 | 1176 | ||
| 1177 | describe("composerDraftStore runtime and interaction settings", () => { | 1177 | describe("composerDraftStore runtime and interaction settings", () => { |
| 1178 | const threadId = ThreadId.makeUnsafe("thread-settings"); | 1178 | const threadId = ThreadId.make("thread-settings"); |
| 1179 | const threadRef = scopeThreadRef(TEST_ENVIRONMENT_ID, threadId); | 1179 | const threadRef = scopeThreadRef(TEST_ENVIRONMENT_ID, threadId); |
| 1180 | 1180 | ||
| 1181 | beforeEach(() => { | 1181 | beforeEach(() => { |
apps/web/src/composerDraftStore.ts+13-16| ... | @@ -926,7 +926,7 @@ function normalizeComposerTarget( | ... | @@ -926,7 +926,7 @@ function normalizeComposerTarget( |
| 926 | ): ComposerThreadTarget | null { | 926 | ): ComposerThreadTarget | null { |
| 927 | if (typeof target === "string") { | 927 | if (typeof target === "string") { |
| 928 | const draftId = target.trim(); | 928 | const draftId = target.trim(); |
| 929 | return draftId.length > 0 ? DraftId.makeUnsafe(draftId) : null; | 929 | return draftId.length > 0 ? DraftId.make(draftId) : null; |
| 930 | } | 930 | } |
| 931 | return target; | 931 | return target; |
| 932 | } | 932 | } |
| ... | @@ -1804,7 +1804,7 @@ const composerDraftStore = create<ComposerDraftStoreState>()( | ... | @@ -1804,7 +1804,7 @@ const composerDraftStore = create<ComposerDraftStoreState>()( |
| 1804 | if (!draftThread || isDraftThreadPromoting(draftThread)) { | 1804 | if (!draftThread || isDraftThreadPromoting(draftThread)) { |
| 1805 | return null; | 1805 | return null; |
| 1806 | } | 1806 | } |
| 1807 | return toProjectDraftSession(DraftId.makeUnsafe(draftId), draftThread); | 1807 | return toProjectDraftSession(DraftId.make(draftId), draftThread); |
| 1808 | }, | 1808 | }, |
| 1809 | getDraftThreadByProjectRef: (projectRef) => { | 1809 | getDraftThreadByProjectRef: (projectRef) => { |
| 1810 | return get().getDraftSessionByProjectRef(projectRef); | 1810 | return get().getDraftSessionByProjectRef(projectRef); |
| ... | @@ -1818,7 +1818,7 @@ const composerDraftStore = create<ComposerDraftStoreState>()( | ... | @@ -1818,7 +1818,7 @@ const composerDraftStore = create<ComposerDraftStoreState>()( |
| 1818 | draftThread.projectId === projectRef.projectId && | 1818 | draftThread.projectId === projectRef.projectId && |
| 1819 | draftThread.environmentId === projectRef.environmentId | 1819 | draftThread.environmentId === projectRef.environmentId |
| 1820 | ) { | 1820 | ) { |
| 1821 | return toProjectDraftSession(DraftId.makeUnsafe(draftId), draftThread); | 1821 | return toProjectDraftSession(DraftId.make(draftId), draftThread); |
| 1822 | } | 1822 | } |
| 1823 | } | 1823 | } |
| 1824 | return null; | 1824 | return null; |
| ... | @@ -1837,7 +1837,7 @@ const composerDraftStore = create<ComposerDraftStoreState>()( | ... | @@ -1837,7 +1837,7 @@ const composerDraftStore = create<ComposerDraftStoreState>()( |
| 1837 | }, | 1837 | }, |
| 1838 | getDraftThread: (threadRef) => { | 1838 | getDraftThread: (threadRef) => { |
| 1839 | if (typeof threadRef === "string") { | 1839 | if (typeof threadRef === "string") { |
| 1840 | return get().getDraftSession(DraftId.makeUnsafe(threadRef)); | 1840 | return get().getDraftSession(DraftId.make(threadRef)); |
| 1841 | } | 1841 | } |
| 1842 | return get().getDraftSessionByRef(threadRef); | 1842 | return get().getDraftSessionByRef(threadRef); |
| 1843 | }, | 1843 | }, |
| ... | @@ -1863,7 +1863,7 @@ const composerDraftStore = create<ComposerDraftStoreState>()( | ... | @@ -1863,7 +1863,7 @@ const composerDraftStore = create<ComposerDraftStoreState>()( |
| 1863 | state.logicalProjectDraftThreadKeyByLogicalProjectKey[normalizedLogicalProjectKey]; | 1863 | state.logicalProjectDraftThreadKeyByLogicalProjectKey[normalizedLogicalProjectKey]; |
| 1864 | const nextDraftThread = createDraftThreadState( | 1864 | const nextDraftThread = createDraftThreadState( |
| 1865 | projectRef, | 1865 | projectRef, |
| 1866 | options?.threadId ?? existingThread?.threadId ?? ThreadId.makeUnsafe(draftId), | 1866 | options?.threadId ?? existingThread?.threadId ?? ThreadId.make(draftId), |
| 1867 | normalizedLogicalProjectKey, | 1867 | normalizedLogicalProjectKey, |
| 1868 | existingThread, | 1868 | existingThread, |
| 1869 | options, | 1869 | options, |
| ... | @@ -2438,10 +2438,9 @@ const composerDraftStore = create<ComposerDraftStoreState>()( | ... | @@ -2438,10 +2438,9 @@ const composerDraftStore = create<ComposerDraftStoreState>()( |
| 2438 | if (!threadKey || !threadId) { | 2438 | if (!threadKey || !threadId) { |
| 2439 | return; | 2439 | return; |
| 2440 | } | 2440 | } |
| 2441 | get().addImages( | 2441 | get().addImages(typeof threadRef === "string" ? DraftId.make(threadKey) : threadRef, [ |
| 2442 | typeof threadRef === "string" ? DraftId.makeUnsafe(threadKey) : threadRef, | 2442 | image, |
| 2443 | [image], | 2443 | ]); |
| 2444 | ); | ||
| 2445 | }, | 2444 | }, |
| 2446 | addImages: (threadRef, images) => { | 2445 | addImages: (threadRef, images) => { |
| 2447 | const threadKey = resolveComposerDraftKey(get(), threadRef) ?? ""; | 2446 | const threadKey = resolveComposerDraftKey(get(), threadRef) ?? ""; |
| ... | @@ -2566,7 +2565,7 @@ const composerDraftStore = create<ComposerDraftStoreState>()( | ... | @@ -2566,7 +2565,7 @@ const composerDraftStore = create<ComposerDraftStoreState>()( |
| 2566 | return; | 2565 | return; |
| 2567 | } | 2566 | } |
| 2568 | get().addTerminalContexts( | 2567 | get().addTerminalContexts( |
| 2569 | typeof threadRef === "string" ? DraftId.makeUnsafe(threadKey) : threadRef, | 2568 | typeof threadRef === "string" ? DraftId.make(threadKey) : threadRef, |
| 2570 | [context], | 2569 | [context], |
| 2571 | ); | 2570 | ); |
| 2572 | }, | 2571 | }, |
| ... | @@ -2799,9 +2798,7 @@ export function useEffectiveComposerModelState(input: { | ... | @@ -2799,9 +2798,7 @@ export function useEffectiveComposerModelState(input: { |
| 2799 | projectModelSelection: ModelSelection | null | undefined; | 2798 | projectModelSelection: ModelSelection | null | undefined; |
| 2800 | settings: UnifiedSettings; | 2799 | settings: UnifiedSettings; |
| 2801 | }): EffectiveComposerModelState { | 2800 | }): EffectiveComposerModelState { |
| 2802 | const draft = useComposerDraftModelState( | 2801 | const draft = useComposerDraftModelState(input.threadRef ?? input.draftId ?? DraftId.make("")); |
| 2803 | input.threadRef ?? input.draftId ?? DraftId.makeUnsafe(""), | ||
| 2804 | ); | ||
| 2805 | 2802 | ||
| 2806 | return useMemo( | 2803 | return useMemo( |
| 2807 | () => | 2804 | () => |
| ... | @@ -2836,7 +2833,7 @@ export function markPromotedDraftThread(threadId: ThreadId): void { | ... | @@ -2836,7 +2833,7 @@ export function markPromotedDraftThread(threadId: ThreadId): void { |
| 2836 | const draftThreadTargets: ComposerThreadTarget[] = []; | 2833 | const draftThreadTargets: ComposerThreadTarget[] = []; |
| 2837 | for (const [draftId, draftThread] of Object.entries(store.draftThreadsByThreadKey)) { | 2834 | for (const [draftId, draftThread] of Object.entries(store.draftThreadsByThreadKey)) { |
| 2838 | if (draftThread.threadId === threadId) { | 2835 | if (draftThread.threadId === threadId) { |
| 2839 | draftThreadTargets.push(DraftId.makeUnsafe(draftId)); | 2836 | draftThreadTargets.push(DraftId.make(draftId)); |
| 2840 | } | 2837 | } |
| 2841 | } | 2838 | } |
| 2842 | if (draftThreadTargets.length === 0) { | 2839 | if (draftThreadTargets.length === 0) { |
| ... | @@ -2854,7 +2851,7 @@ export function markPromotedDraftThreadByRef(threadRef: ScopedThreadRef): void { | ... | @@ -2854,7 +2851,7 @@ export function markPromotedDraftThreadByRef(threadRef: ScopedThreadRef): void { |
| 2854 | draftThread.environmentId === threadRef.environmentId && | 2851 | draftThread.environmentId === threadRef.environmentId && |
| 2855 | draftThread.threadId === threadRef.threadId | 2852 | draftThread.threadId === threadRef.threadId |
| 2856 | ) { | 2853 | ) { |
| 2857 | draftStore.markDraftThreadPromoting(DraftId.makeUnsafe(draftId), threadRef); | 2854 | draftStore.markDraftThreadPromoting(DraftId.make(draftId), threadRef); |
| 2858 | } | 2855 | } |
| 2859 | } | 2856 | } |
| 2860 | } | 2857 | } |
| ... | @@ -2879,7 +2876,7 @@ export function finalizePromotedDraftThreadByRef(threadRef: ScopedThreadRef): vo | ... | @@ -2879,7 +2876,7 @@ export function finalizePromotedDraftThreadByRef(threadRef: ScopedThreadRef): vo |
| 2879 | draftThread.promotedTo.environmentId === threadRef.environmentId && | 2876 | draftThread.promotedTo.environmentId === threadRef.environmentId && |
| 2880 | draftThread.promotedTo.threadId === threadRef.threadId | 2877 | draftThread.promotedTo.threadId === threadRef.threadId |
| 2881 | ) { | 2878 | ) { |
| 2882 | draftStore.finalizePromotedDraftThread(DraftId.makeUnsafe(draftId)); | 2879 | draftStore.finalizePromotedDraftThread(DraftId.make(draftId)); |
| 2883 | } | 2880 | } |
| 2884 | } | 2881 | } |
| 2885 | } | 2882 | } |
apps/web/src/diffRouteSearch.ts+1-1| ... | @@ -28,7 +28,7 @@ export function stripDiffSearchParams<T extends Record<string, unknown>>( | ... | @@ -28,7 +28,7 @@ export function stripDiffSearchParams<T extends Record<string, unknown>>( |
| 28 | export function parseDiffRouteSearch(search: Record<string, unknown>): DiffRouteSearch { | 28 | export function parseDiffRouteSearch(search: Record<string, unknown>): DiffRouteSearch { |
| 29 | const diff = isDiffOpenValue(search.diff) ? "1" : undefined; | 29 | const diff = isDiffOpenValue(search.diff) ? "1" : undefined; |
| 30 | const diffTurnIdRaw = diff ? normalizeSearchString(search.diffTurnId) : undefined; | 30 | const diffTurnIdRaw = diff ? normalizeSearchString(search.diffTurnId) : undefined; |
| 31 | const diffTurnId = diffTurnIdRaw ? TurnId.makeUnsafe(diffTurnIdRaw) : undefined; | 31 | const diffTurnId = diffTurnIdRaw ? TurnId.make(diffTurnIdRaw) : undefined; |
| 32 | const diffFilePath = diff && diffTurnId ? normalizeSearchString(search.diffFilePath) : undefined; | 32 | const diffFilePath = diff && diffTurnId ? normalizeSearchString(search.diffFilePath) : undefined; |
| 33 | 33 | ||
| 34 | return { | 34 | return { |
apps/web/src/environmentGrouping.test.ts+13-13| ... | @@ -16,19 +16,19 @@ import { DEFAULT_INTERACTION_MODE } from "./types"; | ... | @@ -16,19 +16,19 @@ import { DEFAULT_INTERACTION_MODE } from "./types"; |
| 16 | 16 | ||
| 17 | // ── Fixture Identifiers ────────────────────────────────────────────── | 17 | // ── Fixture Identifiers ────────────────────────────────────────────── |
| 18 | 18 | ||
| 19 | const primaryEnvId = EnvironmentId.makeUnsafe("env-primary"); | 19 | const primaryEnvId = EnvironmentId.make("env-primary"); |
| 20 | const remoteEnvId = EnvironmentId.makeUnsafe("env-remote"); | 20 | const remoteEnvId = EnvironmentId.make("env-remote"); |
| 21 | 21 | ||
| 22 | const sharedProjectPrimaryId = ProjectId.makeUnsafe("shared-proj-primary"); | 22 | const sharedProjectPrimaryId = ProjectId.make("shared-proj-primary"); |
| 23 | const sharedProjectRemoteId = ProjectId.makeUnsafe("shared-proj-remote"); | 23 | const sharedProjectRemoteId = ProjectId.make("shared-proj-remote"); |
| 24 | const localOnlyProjectId = ProjectId.makeUnsafe("local-only-proj"); | 24 | const localOnlyProjectId = ProjectId.make("local-only-proj"); |
| 25 | const remoteOnlyProjectId = ProjectId.makeUnsafe("remote-only-proj"); | 25 | const remoteOnlyProjectId = ProjectId.make("remote-only-proj"); |
| 26 | 26 | ||
| 27 | const threadP1 = ThreadId.makeUnsafe("thread-shared-primary-1"); | 27 | const threadP1 = ThreadId.make("thread-shared-primary-1"); |
| 28 | const threadP2 = ThreadId.makeUnsafe("thread-shared-primary-2"); | 28 | const threadP2 = ThreadId.make("thread-shared-primary-2"); |
| 29 | const threadR1 = ThreadId.makeUnsafe("thread-shared-remote-1"); | 29 | const threadR1 = ThreadId.make("thread-shared-remote-1"); |
| 30 | const threadL1 = ThreadId.makeUnsafe("thread-local-only-1"); | 30 | const threadL1 = ThreadId.make("thread-local-only-1"); |
| 31 | const threadRO1 = ThreadId.makeUnsafe("thread-remote-only-1"); | 31 | const threadRO1 = ThreadId.make("thread-remote-only-1"); |
| 32 | 32 | ||
| 33 | const SHARED_REPO_CANONICAL_KEY = "github.com/example/shared-repo"; | 33 | const SHARED_REPO_CANONICAL_KEY = "github.com/example/shared-repo"; |
| 34 | 34 | ||
| ... | @@ -328,7 +328,7 @@ describe("environment grouping", () => { | ... | @@ -328,7 +328,7 @@ describe("environment grouping", () => { |
| 328 | 328 | ||
| 329 | it("returns empty array for nonexistent environment", () => { | 329 | it("returns empty array for nonexistent environment", () => { |
| 330 | const state = makeFixtureState(); | 330 | const state = makeFixtureState(); |
| 331 | const ref = scopeProjectRef(EnvironmentId.makeUnsafe("nonexistent"), sharedProjectPrimaryId); | 331 | const ref = scopeProjectRef(EnvironmentId.make("nonexistent"), sharedProjectPrimaryId); |
| 332 | expect(selectSidebarThreadsForProjectRef(state, ref)).toEqual([]); | 332 | expect(selectSidebarThreadsForProjectRef(state, ref)).toEqual([]); |
| 333 | }); | 333 | }); |
| 334 | }); | 334 | }); |
| ... | @@ -381,7 +381,7 @@ describe("environment grouping", () => { | ... | @@ -381,7 +381,7 @@ describe("environment grouping", () => { |
| 381 | const state = makeFixtureState(); | 381 | const state = makeFixtureState(); |
| 382 | const refs = [ | 382 | const refs = [ |
| 383 | scopeProjectRef(primaryEnvId, sharedProjectPrimaryId), | 383 | scopeProjectRef(primaryEnvId, sharedProjectPrimaryId), |
| 384 | scopeProjectRef(EnvironmentId.makeUnsafe("nonexistent"), ProjectId.makeUnsafe("nope")), | 384 | scopeProjectRef(EnvironmentId.make("nonexistent"), ProjectId.make("nope")), |
| 385 | ]; | 385 | ]; |
| 386 | const threads = selectSidebarThreadsForProjectRefs(state, refs); | 386 | const threads = selectSidebarThreadsForProjectRefs(state, refs); |
| 387 | // Only returns threads from the valid ref | 387 | // Only returns threads from the valid ref |
apps/web/src/environments/primary/bootstrap.test.ts+1-1| ... | @@ -63,7 +63,7 @@ describe("environmentBootstrap", () => { | ... | @@ -63,7 +63,7 @@ describe("environmentBootstrap", () => { |
| 63 | desktopBridge: undefined, | 63 | desktopBridge: undefined, |
| 64 | }); | 64 | }); |
| 65 | writePrimaryEnvironmentDescriptor({ | 65 | writePrimaryEnvironmentDescriptor({ |
| 66 | environmentId: EnvironmentId.makeUnsafe("environment-local"), | 66 | environmentId: EnvironmentId.make("environment-local"), |
| 67 | label: "Bootstrapped environment", | 67 | label: "Bootstrapped environment", |
| 68 | platform: { | 68 | platform: { |
| 69 | os: "darwin", | 69 | os: "darwin", |
apps/web/src/environments/runtime/catalog.test.ts+4-4| ... | @@ -41,7 +41,7 @@ describe("environment runtime catalog stores", () => { | ... | @@ -41,7 +41,7 @@ describe("environment runtime catalog stores", () => { |
| 41 | }); | 41 | }); |
| 42 | 42 | ||
| 43 | it("resets the saved environment registry store state", () => { | 43 | it("resets the saved environment registry store state", () => { |
| 44 | const environmentId = EnvironmentId.makeUnsafe("environment-1"); | 44 | const environmentId = EnvironmentId.make("environment-1"); |
| 45 | 45 | ||
| 46 | useSavedEnvironmentRegistryStore.getState().upsert({ | 46 | useSavedEnvironmentRegistryStore.getState().upsert({ |
| 47 | environmentId, | 47 | environmentId, |
| ... | @@ -60,7 +60,7 @@ describe("environment runtime catalog stores", () => { | ... | @@ -60,7 +60,7 @@ describe("environment runtime catalog stores", () => { |
| 60 | }); | 60 | }); |
| 61 | 61 | ||
| 62 | it("resets the saved environment runtime store state", () => { | 62 | it("resets the saved environment runtime store state", () => { |
| 63 | const environmentId = EnvironmentId.makeUnsafe("environment-1"); | 63 | const environmentId = EnvironmentId.make("environment-1"); |
| 64 | 64 | ||
| 65 | useSavedEnvironmentRuntimeStore.getState().patch(environmentId, { | 65 | useSavedEnvironmentRuntimeStore.getState().patch(environmentId, { |
| 66 | connectionState: "connected", | 66 | connectionState: "connected", |
| ... | @@ -82,7 +82,7 @@ describe("environment runtime catalog stores", () => { | ... | @@ -82,7 +82,7 @@ describe("environment runtime catalog stores", () => { |
| 82 | 82 | ||
| 83 | expect(() => | 83 | expect(() => |
| 84 | useSavedEnvironmentRegistryStore.getState().upsert({ | 84 | useSavedEnvironmentRegistryStore.getState().upsert({ |
| 85 | environmentId: EnvironmentId.makeUnsafe("environment-1"), | 85 | environmentId: EnvironmentId.make("environment-1"), |
| 86 | label: "Remote environment", | 86 | label: "Remote environment", |
| 87 | httpBaseUrl: "https://remote.example.com/", | 87 | httpBaseUrl: "https://remote.example.com/", |
| 88 | wsBaseUrl: "wss://remote.example.com/", | 88 | wsBaseUrl: "wss://remote.example.com/", |
| ... | @@ -121,7 +121,7 @@ describe("environment runtime catalog stores", () => { | ... | @@ -121,7 +121,7 @@ describe("environment runtime catalog stores", () => { |
| 121 | 121 | ||
| 122 | const hydrationPromise = waitForSavedEnvironmentRegistryHydration(); | 122 | const hydrationPromise = waitForSavedEnvironmentRegistryHydration(); |
| 123 | 123 | ||
| 124 | const environmentId = EnvironmentId.makeUnsafe("environment-1"); | 124 | const environmentId = EnvironmentId.make("environment-1"); |
| 125 | const record = { | 125 | const record = { |
| 126 | environmentId, | 126 | environmentId, |
| 127 | label: "Remote environment", | 127 | label: "Remote environment", |
apps/web/src/environments/runtime/connection.test.ts+7-7| ... | @@ -30,7 +30,7 @@ function createTestClient(options?: { | ... | @@ -30,7 +30,7 @@ function createTestClient(options?: { |
| 30 | server: { | 30 | server: { |
| 31 | getConfig: vi.fn(async () => ({ | 31 | getConfig: vi.fn(async () => ({ |
| 32 | environment: { | 32 | environment: { |
| 33 | environmentId: EnvironmentId.makeUnsafe("env-1"), | 33 | environmentId: EnvironmentId.make("env-1"), |
| 34 | }, | 34 | }, |
| 35 | })), | 35 | })), |
| 36 | subscribeConfig: (listener: (event: any) => void) => { | 36 | subscribeConfig: (listener: (event: any) => void) => { |
| ... | @@ -133,7 +133,7 @@ function createTestClient(options?: { | ... | @@ -133,7 +133,7 @@ function createTestClient(options?: { |
| 133 | 133 | ||
| 134 | describe("createEnvironmentConnection", () => { | 134 | describe("createEnvironmentConnection", () => { |
| 135 | it("bootstraps a snapshot immediately for a new connection", async () => { | 135 | it("bootstraps a snapshot immediately for a new connection", async () => { |
| 136 | const environmentId = EnvironmentId.makeUnsafe("env-1"); | 136 | const environmentId = EnvironmentId.make("env-1"); |
| 137 | const { client, getSnapshot } = createTestClient(); | 137 | const { client, getSnapshot } = createTestClient(); |
| 138 | const syncSnapshot = vi.fn(); | 138 | const syncSnapshot = vi.fn(); |
| 139 | 139 | ||
| ... | @@ -168,7 +168,7 @@ describe("createEnvironmentConnection", () => { | ... | @@ -168,7 +168,7 @@ describe("createEnvironmentConnection", () => { |
| 168 | }); | 168 | }); |
| 169 | 169 | ||
| 170 | it("rejects welcome/config identity drift", async () => { | 170 | it("rejects welcome/config identity drift", async () => { |
| 171 | const environmentId = EnvironmentId.makeUnsafe("env-1"); | 171 | const environmentId = EnvironmentId.make("env-1"); |
| 172 | const { client, emitWelcome } = createTestClient(); | 172 | const { client, emitWelcome } = createTestClient(); |
| 173 | 173 | ||
| 174 | const connection = createEnvironmentConnection({ | 174 | const connection = createEnvironmentConnection({ |
| ... | @@ -189,7 +189,7 @@ describe("createEnvironmentConnection", () => { | ... | @@ -189,7 +189,7 @@ describe("createEnvironmentConnection", () => { |
| 189 | applyTerminalEvent: vi.fn(), | 189 | applyTerminalEvent: vi.fn(), |
| 190 | }); | 190 | }); |
| 191 | 191 | ||
| 192 | expect(() => emitWelcome(EnvironmentId.makeUnsafe("env-2"))).toThrow( | 192 | expect(() => emitWelcome(EnvironmentId.make("env-2"))).toThrow( |
| 193 | "Environment connection env-1 changed identity to env-2 via server lifecycle welcome.", | 193 | "Environment connection env-1 changed identity to env-2 via server lifecycle welcome.", |
| 194 | ); | 194 | ); |
| 195 | 195 | ||
| ... | @@ -197,7 +197,7 @@ describe("createEnvironmentConnection", () => { | ... | @@ -197,7 +197,7 @@ describe("createEnvironmentConnection", () => { |
| 197 | }); | 197 | }); |
| 198 | 198 | ||
| 199 | it("rejects ensureBootstrapped when snapshot recovery fails", async () => { | 199 | it("rejects ensureBootstrapped when snapshot recovery fails", async () => { |
| 200 | const environmentId = EnvironmentId.makeUnsafe("env-1"); | 200 | const environmentId = EnvironmentId.make("env-1"); |
| 201 | const snapshotError = new Error("snapshot failed"); | 201 | const snapshotError = new Error("snapshot failed"); |
| 202 | const { client } = createTestClient({ | 202 | const { client } = createTestClient({ |
| 203 | getSnapshot: async () => { | 203 | getSnapshot: async () => { |
| ... | @@ -229,7 +229,7 @@ describe("createEnvironmentConnection", () => { | ... | @@ -229,7 +229,7 @@ describe("createEnvironmentConnection", () => { |
| 229 | }); | 229 | }); |
| 230 | 230 | ||
| 231 | it("retries replay recovery after transport disconnects during resubscribe", async () => { | 231 | it("retries replay recovery after transport disconnects during resubscribe", async () => { |
| 232 | const environmentId = EnvironmentId.makeUnsafe("env-1"); | 232 | const environmentId = EnvironmentId.make("env-1"); |
| 233 | let replayAttempts = 0; | 233 | let replayAttempts = 0; |
| 234 | const applyEventBatch = vi.fn(); | 234 | const applyEventBatch = vi.fn(); |
| 235 | const { client, replayEvents, triggerDomainResubscribe } = createTestClient({ | 235 | const { client, replayEvents, triggerDomainResubscribe } = createTestClient({ |
| ... | @@ -287,7 +287,7 @@ describe("createEnvironmentConnection", () => { | ... | @@ -287,7 +287,7 @@ describe("createEnvironmentConnection", () => { |
| 287 | await connection.dispose(); | 287 | await connection.dispose(); |
| 288 | }); | 288 | }); |
| 289 | it("swallows replay recovery failures triggered by resubscribe", async () => { | 289 | it("swallows replay recovery failures triggered by resubscribe", async () => { |
| 290 | const environmentId = EnvironmentId.makeUnsafe("env-1"); | 290 | const environmentId = EnvironmentId.make("env-1"); |
| 291 | const snapshotError = new Error("snapshot failed"); | 291 | const snapshotError = new Error("snapshot failed"); |
| 292 | let snapshotCalls = 0; | 292 | let snapshotCalls = 0; |
| 293 | const { client, triggerDomainResubscribe } = createTestClient({ | 293 | const { client, triggerDomainResubscribe } = createTestClient({ |
apps/web/src/environments/runtime/service.addSavedEnvironment.test.ts+2-2| ... | @@ -68,7 +68,7 @@ describe("addSavedEnvironment", () => { | ... | @@ -68,7 +68,7 @@ describe("addSavedEnvironment", () => { |
| 68 | credential: "pairing-code", | 68 | credential: "pairing-code", |
| 69 | }); | 69 | }); |
| 70 | mockFetchRemoteEnvironmentDescriptor.mockResolvedValue({ | 70 | mockFetchRemoteEnvironmentDescriptor.mockResolvedValue({ |
| 71 | environmentId: EnvironmentId.makeUnsafe("environment-1"), | 71 | environmentId: EnvironmentId.make("environment-1"), |
| 72 | label: "Remote environment", | 72 | label: "Remote environment", |
| 73 | }); | 73 | }); |
| 74 | mockBootstrapRemoteBearerSession.mockResolvedValue({ | 74 | mockBootstrapRemoteBearerSession.mockResolvedValue({ |
| ... | @@ -94,7 +94,7 @@ describe("addSavedEnvironment", () => { | ... | @@ -94,7 +94,7 @@ describe("addSavedEnvironment", () => { |
| 94 | 94 | ||
| 95 | expect(mockPersistSavedEnvironmentRecord).toHaveBeenCalledTimes(1); | 95 | expect(mockPersistSavedEnvironmentRecord).toHaveBeenCalledTimes(1); |
| 96 | expect(mockWriteSavedEnvironmentBearerToken).toHaveBeenCalledWith( | 96 | expect(mockWriteSavedEnvironmentBearerToken).toHaveBeenCalledWith( |
| 97 | EnvironmentId.makeUnsafe("environment-1"), | 97 | EnvironmentId.make("environment-1"), |
| 98 | "bearer-token", | 98 | "bearer-token", |
| 99 | ); | 99 | ); |
| 100 | expect(mockSetSavedEnvironmentRegistry).toHaveBeenCalledWith([]); | 100 | expect(mockSetSavedEnvironmentRegistry).toHaveBeenCalledWith([]); |
apps/web/src/environments/runtime/service.ts+1-1| ... | @@ -281,7 +281,7 @@ function createEnvironmentConnectionHandlers() { | ... | @@ -281,7 +281,7 @@ function createEnvironmentConnectionHandlers() { |
| 281 | reconcileSnapshotDerivedState(); | 281 | reconcileSnapshotDerivedState(); |
| 282 | }, | 282 | }, |
| 283 | applyTerminalEvent: (event: TerminalEvent, environmentId: EnvironmentId) => { | 283 | applyTerminalEvent: (event: TerminalEvent, environmentId: EnvironmentId) => { |
| 284 | const threadRef = scopeThreadRef(environmentId, ThreadId.makeUnsafe(event.threadId)); | 284 | const threadRef = scopeThreadRef(environmentId, ThreadId.make(event.threadId)); |
| 285 | const serverThread = selectThreadByRef(useStore.getState(), threadRef); | 285 | const serverThread = selectThreadByRef(useStore.getState(), threadRef); |
| 286 | const hasDraftThread = | 286 | const hasDraftThread = |
| 287 | useComposerDraftStore.getState().getDraftThreadByRef(threadRef) !== null; | 287 | useComposerDraftStore.getState().getDraftThreadByRef(threadRef) !== null; |
apps/web/src/historyBootstrap.test.ts+1-1| ... | @@ -3,7 +3,7 @@ import { describe, expect, it } from "vitest"; | ... | @@ -3,7 +3,7 @@ import { describe, expect, it } from "vitest"; |
| 3 | 3 | ||
| 4 | import { buildBootstrapInput } from "./historyBootstrap"; | 4 | import { buildBootstrapInput } from "./historyBootstrap"; |
| 5 | 5 | ||
| 6 | const messageId = (value: string) => MessageId.makeUnsafe(value); | 6 | const messageId = (value: string) => MessageId.make(value); |
| 7 | 7 | ||
| 8 | describe("buildBootstrapInput", () => { | 8 | describe("buildBootstrapInput", () => { |
| 9 | it("includes full transcript when under budget", () => { | 9 | it("includes full transcript when under budget", () => { |
apps/web/src/lib/contextWindow.test.ts+2-2| ... | @@ -5,12 +5,12 @@ import { deriveLatestContextWindowSnapshot, formatContextWindowTokens } from "./ | ... | @@ -5,12 +5,12 @@ import { deriveLatestContextWindowSnapshot, formatContextWindowTokens } from "./ |
| 5 | 5 | ||
| 6 | function makeActivity(id: string, kind: string, payload: unknown): OrchestrationThreadActivity { | 6 | function makeActivity(id: string, kind: string, payload: unknown): OrchestrationThreadActivity { |
| 7 | return { | 7 | return { |
| 8 | id: EventId.makeUnsafe(id), | 8 | id: EventId.make(id), |
| 9 | tone: "info", | 9 | tone: "info", |
| 10 | kind, | 10 | kind, |
| 11 | summary: kind, | 11 | summary: kind, |
| 12 | payload, | 12 | payload, |
| 13 | turnId: TurnId.makeUnsafe("turn-1"), | 13 | turnId: TurnId.make("turn-1"), |
| 14 | createdAt: "2026-03-23T00:00:00.000Z", | 14 | createdAt: "2026-03-23T00:00:00.000Z", |
| 15 | }; | 15 | }; |
| 16 | } | 16 | } |
apps/web/src/lib/gitReactQuery.test.ts+2-2| ... | @@ -34,8 +34,8 @@ const BRANCH_SEARCH_RESULT: InfiniteData<GitListBranchesResult, number> = { | ... | @@ -34,8 +34,8 @@ const BRANCH_SEARCH_RESULT: InfiniteData<GitListBranchesResult, number> = { |
| 34 | pages: [BRANCH_QUERY_RESULT], | 34 | pages: [BRANCH_QUERY_RESULT], |
| 35 | pageParams: [0], | 35 | pageParams: [0], |
| 36 | }; | 36 | }; |
| 37 | const ENVIRONMENT_A = EnvironmentId.makeUnsafe("environment-a"); | 37 | const ENVIRONMENT_A = EnvironmentId.make("environment-a"); |
| 38 | const ENVIRONMENT_B = EnvironmentId.makeUnsafe("environment-b"); | 38 | const ENVIRONMENT_B = EnvironmentId.make("environment-b"); |
| 39 | 39 | ||
| 40 | describe("gitMutationKeys", () => { | 40 | describe("gitMutationKeys", () => { |
| 41 | it("scopes stacked action keys by cwd", () => { | 41 | it("scopes stacked action keys by cwd", () => { |
apps/web/src/lib/gitStatusState.test.ts+2-2| ... | @@ -34,8 +34,8 @@ function registerListener<T>(listeners: Set<(event: T) => void>, listener: (even | ... | @@ -34,8 +34,8 @@ function registerListener<T>(listeners: Set<(event: T) => void>, listener: (even |
| 34 | } | 34 | } |
| 35 | 35 | ||
| 36 | const gitStatusListeners = new Set<(event: GitStatusResult) => void>(); | 36 | const gitStatusListeners = new Set<(event: GitStatusResult) => void>(); |
| 37 | const ENVIRONMENT_ID = EnvironmentId.makeUnsafe("environment-local"); | 37 | const ENVIRONMENT_ID = EnvironmentId.make("environment-local"); |
| 38 | const OTHER_ENVIRONMENT_ID = EnvironmentId.makeUnsafe("environment-remote"); | 38 | const OTHER_ENVIRONMENT_ID = EnvironmentId.make("environment-remote"); |
| 39 | const TARGET = { environmentId: ENVIRONMENT_ID, cwd: "/repo" } as const; | 39 | const TARGET = { environmentId: ENVIRONMENT_ID, cwd: "/repo" } as const; |
| 40 | const FRESH_TARGET = { environmentId: ENVIRONMENT_ID, cwd: "/fresh" } as const; | 40 | const FRESH_TARGET = { environmentId: ENVIRONMENT_ID, cwd: "/fresh" } as const; |
| 41 | 41 |
apps/web/src/lib/providerReactQuery.test.ts+2-2| ... | @@ -4,8 +4,8 @@ import { afterEach, describe, expect, it, vi } from "vitest"; | ... | @@ -4,8 +4,8 @@ import { afterEach, describe, expect, it, vi } from "vitest"; |
| 4 | import { checkpointDiffQueryOptions, providerQueryKeys } from "./providerReactQuery"; | 4 | import { checkpointDiffQueryOptions, providerQueryKeys } from "./providerReactQuery"; |
| 5 | import * as environmentApi from "../environmentApi"; | 5 | import * as environmentApi from "../environmentApi"; |
| 6 | 6 | ||
| 7 | const threadId = ThreadId.makeUnsafe("thread-id"); | 7 | const threadId = ThreadId.make("thread-id"); |
| 8 | const environmentId = EnvironmentId.makeUnsafe("environment-local"); | 8 | const environmentId = EnvironmentId.make("environment-local"); |
| 9 | 9 | ||
| 10 | function mockNativeApi(input: { | 10 | function mockNativeApi(input: { |
| 11 | getTurnDiff: ReturnType<typeof vi.fn>; | 11 | getTurnDiff: ReturnType<typeof vi.fn>; |
apps/web/src/lib/terminalContext.test.ts+1-1| ... | @@ -25,7 +25,7 @@ import { | ... | @@ -25,7 +25,7 @@ import { |
| 25 | function makeContext(overrides?: Partial<TerminalContextDraft>): TerminalContextDraft { | 25 | function makeContext(overrides?: Partial<TerminalContextDraft>): TerminalContextDraft { |
| 26 | return { | 26 | return { |
| 27 | id: "context-1", | 27 | id: "context-1", |
| 28 | threadId: ThreadId.makeUnsafe("thread-1"), | 28 | threadId: ThreadId.make("thread-1"), |
| 29 | terminalId: "default", | 29 | terminalId: "default", |
| 30 | terminalLabel: "Terminal 1", | 30 | terminalLabel: "Terminal 1", |
| 31 | lineStart: 12, | 31 | lineStart: 12, |
apps/web/src/lib/terminalStateCleanup.test.ts+1-1| ... | @@ -4,7 +4,7 @@ import { describe, expect, it } from "vitest"; | ... | @@ -4,7 +4,7 @@ import { describe, expect, it } from "vitest"; |
| 4 | 4 | ||
| 5 | import { collectActiveTerminalThreadIds } from "./terminalStateCleanup"; | 5 | import { collectActiveTerminalThreadIds } from "./terminalStateCleanup"; |
| 6 | 6 | ||
| 7 | const threadId = (id: string): ThreadId => ThreadId.makeUnsafe(id); | 7 | const threadId = (id: string): ThreadId => ThreadId.make(id); |
| 8 | const threadKey = (environmentId: string, id: string): string => | 8 | const threadKey = (environmentId: string, id: string): string => |
| 9 | scopedThreadKey(scopeThreadRef(environmentId as never, threadId(id))); | 9 | scopedThreadKey(scopeThreadRef(environmentId as never, threadId(id))); |
| 10 | 10 |
apps/web/src/lib/utils.ts+5-5| ... | @@ -28,12 +28,12 @@ export function randomUUID(): string { | ... | @@ -28,12 +28,12 @@ export function randomUUID(): string { |
| 28 | return Effect.runSync(Random.nextUUIDv4); | 28 | return Effect.runSync(Random.nextUUIDv4); |
| 29 | } | 29 | } |
| 30 | 30 | ||
| 31 | export const newCommandId = (): CommandId => CommandId.makeUnsafe(randomUUID()); | 31 | export const newCommandId = (): CommandId => CommandId.make(randomUUID()); |
| 32 | 32 | ||
| 33 | export const newProjectId = (): ProjectId => ProjectId.makeUnsafe(randomUUID()); | 33 | export const newProjectId = (): ProjectId => ProjectId.make(randomUUID()); |
| 34 | 34 | ||
| 35 | export const newThreadId = (): ThreadId => ThreadId.makeUnsafe(randomUUID()); | 35 | export const newThreadId = (): ThreadId => ThreadId.make(randomUUID()); |
| 36 | 36 | ||
| 37 | export const newDraftId = (): DraftId => DraftId.makeUnsafe(randomUUID()); | 37 | export const newDraftId = (): DraftId => DraftId.make(randomUUID()); |
| 38 | 38 | ||
| 39 | export const newMessageId = (): MessageId => MessageId.makeUnsafe(randomUUID()); | 39 | export const newMessageId = (): MessageId => MessageId.make(randomUUID()); |
apps/web/src/localApi.test.ts+18-22| ... | @@ -104,10 +104,10 @@ vi.mock("./environments/runtime", () => ({ | ... | @@ -104,10 +104,10 @@ vi.mock("./environments/runtime", () => ({ |
| 104 | httpBaseUrl: "http://localhost:3000", | 104 | httpBaseUrl: "http://localhost:3000", |
| 105 | wsBaseUrl: "ws://localhost:3000", | 105 | wsBaseUrl: "ws://localhost:3000", |
| 106 | }, | 106 | }, |
| 107 | environmentId: EnvironmentId.makeUnsafe("environment-local"), | 107 | environmentId: EnvironmentId.make("environment-local"), |
| 108 | }, | 108 | }, |
| 109 | client: rpcClientMock, | 109 | client: rpcClientMock, |
| 110 | environmentId: EnvironmentId.makeUnsafe("environment-local"), | 110 | environmentId: EnvironmentId.make("environment-local"), |
| 111 | ensureBootstrapped: async () => undefined, | 111 | ensureBootstrapped: async () => undefined, |
| 112 | reconnect: async () => undefined, | 112 | reconnect: async () => undefined, |
| 113 | dispose: async () => undefined, | 113 | dispose: async () => undefined, |
| ... | @@ -214,7 +214,7 @@ const defaultProviders: ReadonlyArray<ServerProvider> = [ | ... | @@ -214,7 +214,7 @@ const defaultProviders: ReadonlyArray<ServerProvider> = [ |
| 214 | ]; | 214 | ]; |
| 215 | 215 | ||
| 216 | const baseEnvironment = { | 216 | const baseEnvironment = { |
| 217 | environmentId: EnvironmentId.makeUnsafe("environment-local"), | 217 | environmentId: EnvironmentId.make("environment-local"), |
| 218 | label: "Local environment", | 218 | label: "Local environment", |
| 219 | platform: { | 219 | platform: { |
| 220 | os: "darwin" as const, | 220 | os: "darwin" as const, |
| ... | @@ -315,9 +315,9 @@ describe("wsApi", () => { | ... | @@ -315,9 +315,9 @@ describe("wsApi", () => { |
| 315 | 315 | ||
| 316 | const orchestrationEvent = { | 316 | const orchestrationEvent = { |
| 317 | sequence: 1, | 317 | sequence: 1, |
| 318 | eventId: EventId.makeUnsafe("event-1"), | 318 | eventId: EventId.make("event-1"), |
| 319 | aggregateKind: "project", | 319 | aggregateKind: "project", |
| 320 | aggregateId: ProjectId.makeUnsafe("project-1"), | 320 | aggregateId: ProjectId.make("project-1"), |
| 321 | occurredAt: "2026-02-24T00:00:00.000Z", | 321 | occurredAt: "2026-02-24T00:00:00.000Z", |
| 322 | commandId: null, | 322 | commandId: null, |
| 323 | causationEventId: null, | 323 | causationEventId: null, |
| ... | @@ -325,7 +325,7 @@ describe("wsApi", () => { | ... | @@ -325,7 +325,7 @@ describe("wsApi", () => { |
| 325 | metadata: {}, | 325 | metadata: {}, |
| 326 | type: "project.created", | 326 | type: "project.created", |
| 327 | payload: { | 327 | payload: { |
| 328 | projectId: ProjectId.makeUnsafe("project-1"), | 328 | projectId: ProjectId.make("project-1"), |
| 329 | title: "Project", | 329 | title: "Project", |
| 330 | workspaceRoot: "/tmp/workspace", | 330 | workspaceRoot: "/tmp/workspace", |
| 331 | defaultModelSelection: { | 331 | defaultModelSelection: { |
| ... | @@ -390,8 +390,8 @@ describe("wsApi", () => { | ... | @@ -390,8 +390,8 @@ describe("wsApi", () => { |
| 390 | const api = createEnvironmentApi(rpcClientMock as never); | 390 | const api = createEnvironmentApi(rpcClientMock as never); |
| 391 | const command = { | 391 | const command = { |
| 392 | type: "project.create", | 392 | type: "project.create", |
| 393 | commandId: CommandId.makeUnsafe("cmd-1"), | 393 | commandId: CommandId.make("cmd-1"), |
| 394 | projectId: ProjectId.makeUnsafe("project-1"), | 394 | projectId: ProjectId.make("project-1"), |
| 395 | title: "Project", | 395 | title: "Project", |
| 396 | workspaceRoot: "/tmp/project", | 396 | workspaceRoot: "/tmp/project", |
| 397 | defaultModelSelection: { | 397 | defaultModelSelection: { |
| ... | @@ -429,7 +429,7 @@ describe("wsApi", () => { | ... | @@ -429,7 +429,7 @@ describe("wsApi", () => { |
| 429 | 429 | ||
| 430 | const api = createEnvironmentApi(rpcClientMock as never); | 430 | const api = createEnvironmentApi(rpcClientMock as never); |
| 431 | await api.orchestration.getFullThreadDiff({ | 431 | await api.orchestration.getFullThreadDiff({ |
| 432 | threadId: ThreadId.makeUnsafe("thread-1"), | 432 | threadId: ThreadId.make("thread-1"), |
| 433 | toTurnCount: 1, | 433 | toTurnCount: 1, |
| 434 | }); | 434 | }); |
| 435 | 435 | ||
| ... | @@ -535,14 +535,12 @@ describe("wsApi", () => { | ... | @@ -535,14 +535,12 @@ describe("wsApi", () => { |
| 535 | }); | 535 | }); |
| 536 | await api.persistence.getSavedEnvironmentRegistry(); | 536 | await api.persistence.getSavedEnvironmentRegistry(); |
| 537 | await api.persistence.setSavedEnvironmentRegistry([]); | 537 | await api.persistence.setSavedEnvironmentRegistry([]); |
| 538 | await api.persistence.getSavedEnvironmentSecret(EnvironmentId.makeUnsafe("environment-local")); | 538 | await api.persistence.getSavedEnvironmentSecret(EnvironmentId.make("environment-local")); |
| 539 | await api.persistence.setSavedEnvironmentSecret( | 539 | await api.persistence.setSavedEnvironmentSecret( |
| 540 | EnvironmentId.makeUnsafe("environment-local"), | 540 | EnvironmentId.make("environment-local"), |
| 541 | "bearer-token", | 541 | "bearer-token", |
| 542 | ); | 542 | ); |
| 543 | await api.persistence.removeSavedEnvironmentSecret( | 543 | await api.persistence.removeSavedEnvironmentSecret(EnvironmentId.make("environment-local")); |
| 544 | EnvironmentId.makeUnsafe("environment-local"), | ||
| 545 | ); | ||
| 546 | 544 | ||
| 547 | expect(getClientSettings).toHaveBeenCalledWith(); | 545 | expect(getClientSettings).toHaveBeenCalledWith(); |
| 548 | expect(setClientSettings).toHaveBeenCalledWith({ | 546 | expect(setClientSettings).toHaveBeenCalledWith({ |
| ... | @@ -574,7 +572,7 @@ describe("wsApi", () => { | ... | @@ -574,7 +572,7 @@ describe("wsApi", () => { |
| 574 | }); | 572 | }); |
| 575 | await api.persistence.setSavedEnvironmentRegistry([ | 573 | await api.persistence.setSavedEnvironmentRegistry([ |
| 576 | { | 574 | { |
| 577 | environmentId: EnvironmentId.makeUnsafe("environment-local"), | 575 | environmentId: EnvironmentId.make("environment-local"), |
| 578 | label: "Primary", | 576 | label: "Primary", |
| 579 | httpBaseUrl: "http://localhost:3000", | 577 | httpBaseUrl: "http://localhost:3000", |
| 580 | wsBaseUrl: "ws://localhost:3000", | 578 | wsBaseUrl: "ws://localhost:3000", |
| ... | @@ -583,7 +581,7 @@ describe("wsApi", () => { | ... | @@ -583,7 +581,7 @@ describe("wsApi", () => { |
| 583 | }, | 581 | }, |
| 584 | ]); | 582 | ]); |
| 585 | await api.persistence.setSavedEnvironmentSecret( | 583 | await api.persistence.setSavedEnvironmentSecret( |
| 586 | EnvironmentId.makeUnsafe("environment-local"), | 584 | EnvironmentId.make("environment-local"), |
| 587 | "bearer-token", | 585 | "bearer-token", |
| 588 | ); | 586 | ); |
| 589 | 587 | ||
| ... | @@ -597,7 +595,7 @@ describe("wsApi", () => { | ... | @@ -597,7 +595,7 @@ describe("wsApi", () => { |
| 597 | }); | 595 | }); |
| 598 | await expect(api.persistence.getSavedEnvironmentRegistry()).resolves.toEqual([ | 596 | await expect(api.persistence.getSavedEnvironmentRegistry()).resolves.toEqual([ |
| 599 | { | 597 | { |
| 600 | environmentId: EnvironmentId.makeUnsafe("environment-local"), | 598 | environmentId: EnvironmentId.make("environment-local"), |
| 601 | label: "Primary", | 599 | label: "Primary", |
| 602 | httpBaseUrl: "http://localhost:3000", | 600 | httpBaseUrl: "http://localhost:3000", |
| 603 | wsBaseUrl: "ws://localhost:3000", | 601 | wsBaseUrl: "ws://localhost:3000", |
| ... | @@ -606,15 +604,13 @@ describe("wsApi", () => { | ... | @@ -606,15 +604,13 @@ describe("wsApi", () => { |
| 606 | }, | 604 | }, |
| 607 | ]); | 605 | ]); |
| 608 | await expect( | 606 | await expect( |
| 609 | api.persistence.getSavedEnvironmentSecret(EnvironmentId.makeUnsafe("environment-local")), | 607 | api.persistence.getSavedEnvironmentSecret(EnvironmentId.make("environment-local")), |
| 610 | ).resolves.toBe("bearer-token"); | 608 | ).resolves.toBe("bearer-token"); |
| 611 | 609 | ||
| 612 | await api.persistence.removeSavedEnvironmentSecret( | 610 | await api.persistence.removeSavedEnvironmentSecret(EnvironmentId.make("environment-local")); |
| 613 | EnvironmentId.makeUnsafe("environment-local"), | ||
| 614 | ); | ||
| 615 | 611 | ||
| 616 | await expect( | 612 | await expect( |
| 617 | api.persistence.getSavedEnvironmentSecret(EnvironmentId.makeUnsafe("environment-local")), | 613 | api.persistence.getSavedEnvironmentSecret(EnvironmentId.make("environment-local")), |
| 618 | ).resolves.toBeNull(); | 614 | ).resolves.toBeNull(); |
| 619 | }); | 615 | }); |
| 620 | }); | 616 | }); |
apps/web/src/orchestrationEventEffects.test.ts+12-12| ... | @@ -19,14 +19,14 @@ function makeEvent<T extends OrchestrationEvent["type"]>( | ... | @@ -19,14 +19,14 @@ function makeEvent<T extends OrchestrationEvent["type"]>( |
| 19 | const sequence = overrides.sequence ?? 1; | 19 | const sequence = overrides.sequence ?? 1; |
| 20 | return { | 20 | return { |
| 21 | sequence, | 21 | sequence, |
| 22 | eventId: EventId.makeUnsafe(`event-${sequence}`), | 22 | eventId: EventId.make(`event-${sequence}`), |
| 23 | aggregateKind: "thread", | 23 | aggregateKind: "thread", |
| 24 | aggregateId: | 24 | aggregateId: |
| 25 | "threadId" in payload | 25 | "threadId" in payload |
| 26 | ? payload.threadId | 26 | ? payload.threadId |
| 27 | : "projectId" in payload | 27 | : "projectId" in payload |
| 28 | ? payload.projectId | 28 | ? payload.projectId |
| 29 | : ProjectId.makeUnsafe("project-1"), | 29 | : ProjectId.make("project-1"), |
| 30 | occurredAt: "2026-02-27T00:00:00.000Z", | 30 | occurredAt: "2026-02-27T00:00:00.000Z", |
| 31 | commandId: null, | 31 | commandId: null, |
| 32 | causationEventId: null, | 32 | causationEventId: null, |
| ... | @@ -40,14 +40,14 @@ function makeEvent<T extends OrchestrationEvent["type"]>( | ... | @@ -40,14 +40,14 @@ function makeEvent<T extends OrchestrationEvent["type"]>( |
| 40 | 40 | ||
| 41 | describe("deriveOrchestrationBatchEffects", () => { | 41 | describe("deriveOrchestrationBatchEffects", () => { |
| 42 | it("targets draft promotion and terminal cleanup from thread lifecycle events", () => { | 42 | it("targets draft promotion and terminal cleanup from thread lifecycle events", () => { |
| 43 | const createdThreadId = ThreadId.makeUnsafe("thread-created"); | 43 | const createdThreadId = ThreadId.make("thread-created"); |
| 44 | const deletedThreadId = ThreadId.makeUnsafe("thread-deleted"); | 44 | const deletedThreadId = ThreadId.make("thread-deleted"); |
| 45 | const archivedThreadId = ThreadId.makeUnsafe("thread-archived"); | 45 | const archivedThreadId = ThreadId.make("thread-archived"); |
| 46 | 46 | ||
| 47 | const effects = deriveOrchestrationBatchEffects([ | 47 | const effects = deriveOrchestrationBatchEffects([ |
| 48 | makeEvent("thread.created", { | 48 | makeEvent("thread.created", { |
| 49 | threadId: createdThreadId, | 49 | threadId: createdThreadId, |
| 50 | projectId: ProjectId.makeUnsafe("project-1"), | 50 | projectId: ProjectId.make("project-1"), |
| 51 | title: "Created thread", | 51 | title: "Created thread", |
| 52 | modelSelection: { provider: "codex", model: "gpt-5-codex" }, | 52 | modelSelection: { provider: "codex", model: "gpt-5-codex" }, |
| 53 | runtimeMode: "full-access", | 53 | runtimeMode: "full-access", |
| ... | @@ -75,7 +75,7 @@ describe("deriveOrchestrationBatchEffects", () => { | ... | @@ -75,7 +75,7 @@ describe("deriveOrchestrationBatchEffects", () => { |
| 75 | }); | 75 | }); |
| 76 | 76 | ||
| 77 | it("keeps only the final lifecycle outcome for a thread within one batch", () => { | 77 | it("keeps only the final lifecycle outcome for a thread within one batch", () => { |
| 78 | const threadId = ThreadId.makeUnsafe("thread-1"); | 78 | const threadId = ThreadId.make("thread-1"); |
| 79 | 79 | ||
| 80 | const effects = deriveOrchestrationBatchEffects([ | 80 | const effects = deriveOrchestrationBatchEffects([ |
| 81 | makeEvent("thread.deleted", { | 81 | makeEvent("thread.deleted", { |
| ... | @@ -84,7 +84,7 @@ describe("deriveOrchestrationBatchEffects", () => { | ... | @@ -84,7 +84,7 @@ describe("deriveOrchestrationBatchEffects", () => { |
| 84 | }), | 84 | }), |
| 85 | makeEvent("thread.created", { | 85 | makeEvent("thread.created", { |
| 86 | threadId, | 86 | threadId, |
| 87 | projectId: ProjectId.makeUnsafe("project-1"), | 87 | projectId: ProjectId.make("project-1"), |
| 88 | title: "Recreated thread", | 88 | title: "Recreated thread", |
| 89 | modelSelection: { provider: "codex", model: "gpt-5-codex" }, | 89 | modelSelection: { provider: "codex", model: "gpt-5-codex" }, |
| 90 | runtimeMode: "full-access", | 90 | runtimeMode: "full-access", |
| ... | @@ -96,12 +96,12 @@ describe("deriveOrchestrationBatchEffects", () => { | ... | @@ -96,12 +96,12 @@ describe("deriveOrchestrationBatchEffects", () => { |
| 96 | }), | 96 | }), |
| 97 | makeEvent("thread.turn-diff-completed", { | 97 | makeEvent("thread.turn-diff-completed", { |
| 98 | threadId, | 98 | threadId, |
| 99 | turnId: TurnId.makeUnsafe("turn-1"), | 99 | turnId: TurnId.make("turn-1"), |
| 100 | checkpointTurnCount: 1, | 100 | checkpointTurnCount: 1, |
| 101 | checkpointRef: CheckpointRef.makeUnsafe("checkpoint-1"), | 101 | checkpointRef: CheckpointRef.make("checkpoint-1"), |
| 102 | status: "ready", | 102 | status: "ready", |
| 103 | files: [], | 103 | files: [], |
| 104 | assistantMessageId: MessageId.makeUnsafe("assistant-1"), | 104 | assistantMessageId: MessageId.make("assistant-1"), |
| 105 | completedAt: "2026-02-27T00:00:03.000Z", | 105 | completedAt: "2026-02-27T00:00:03.000Z", |
| 106 | }), | 106 | }), |
| 107 | ]); | 107 | ]); |
| ... | @@ -113,7 +113,7 @@ describe("deriveOrchestrationBatchEffects", () => { | ... | @@ -113,7 +113,7 @@ describe("deriveOrchestrationBatchEffects", () => { |
| 113 | }); | 113 | }); |
| 114 | 114 | ||
| 115 | it("does not retain archive cleanup when a thread is unarchived later in the same batch", () => { | 115 | it("does not retain archive cleanup when a thread is unarchived later in the same batch", () => { |
| 116 | const threadId = ThreadId.makeUnsafe("thread-1"); | 116 | const threadId = ThreadId.make("thread-1"); |
| 117 | 117 | ||
| 118 | const effects = deriveOrchestrationBatchEffects([ | 118 | const effects = deriveOrchestrationBatchEffects([ |
| 119 | makeEvent("thread.archived", { | 119 | makeEvent("thread.archived", { |
apps/web/src/projectScripts.ts+1-1| ... | @@ -22,7 +22,7 @@ function normalizeScriptId(value: string): string { | ... | @@ -22,7 +22,7 @@ function normalizeScriptId(value: string): string { |
| 22 | } | 22 | } |
| 23 | 23 | ||
| 24 | export const commandForProjectScript = (scriptId: string): KeybindingCommand => | 24 | export const commandForProjectScript = (scriptId: string): KeybindingCommand => |
| 25 | SCRIPT_RUN_COMMAND_PATTERN.makeUnsafe(`script.${scriptId}.run`); | 25 | SCRIPT_RUN_COMMAND_PATTERN.make(`script.${scriptId}.run`); |
| 26 | 26 | ||
| 27 | export function projectScriptIdFromCommand(command: string): string | null { | 27 | export function projectScriptIdFromCommand(command: string): string | null { |
| 28 | const trimmed = command.trim(); | 28 | const trimmed = command.trim(); |
apps/web/src/routes/_chat.draft.$draftId.tsx+1-1| ... | @@ -11,7 +11,7 @@ import { buildThreadRouteParams } from "../threadRoutes"; | ... | @@ -11,7 +11,7 @@ import { buildThreadRouteParams } from "../threadRoutes"; |
| 11 | function DraftChatThreadRouteView() { | 11 | function DraftChatThreadRouteView() { |
| 12 | const navigate = useNavigate(); | 12 | const navigate = useNavigate(); |
| 13 | const { draftId: rawDraftId } = Route.useParams(); | 13 | const { draftId: rawDraftId } = Route.useParams(); |
| 14 | const draftId = DraftId.makeUnsafe(rawDraftId); | 14 | const draftId = DraftId.make(rawDraftId); |
| 15 | const draftSession = useComposerDraftStore((store) => store.getDraftSession(draftId)); | 15 | const draftSession = useComposerDraftStore((store) => store.getDraftSession(draftId)); |
| 16 | const serverThread = useStore( | 16 | const serverThread = useStore( |
| 17 | useMemo( | 17 | useMemo( |
apps/web/src/rpc/protocol.ts+4-4| ... | @@ -154,8 +154,8 @@ export function createWsRpcProtocolLayer( | ... | @@ -154,8 +154,8 @@ export function createWsRpcProtocolLayer( |
| 154 | }), | 154 | }), |
| 155 | (protocol) => ({ | 155 | (protocol) => ({ |
| 156 | ...protocol, | 156 | ...protocol, |
| 157 | run: (writeResponse) => | 157 | run: (clientId, writeResponse) => |
| 158 | protocol.run((response) => { | 158 | protocol.run(clientId, (response) => { |
| 159 | if (response._tag === "Chunk" || response._tag === "Exit") { | 159 | if (response._tag === "Chunk" || response._tag === "Exit") { |
| 160 | acknowledgeRpcRequest(response.requestId); | 160 | acknowledgeRpcRequest(response.requestId); |
| 161 | } else if (response._tag === "ClientProtocolError" || response._tag === "Defect") { | 161 | } else if (response._tag === "ClientProtocolError" || response._tag === "Defect") { |
| ... | @@ -163,11 +163,11 @@ export function createWsRpcProtocolLayer( | ... | @@ -163,11 +163,11 @@ export function createWsRpcProtocolLayer( |
| 163 | } | 163 | } |
| 164 | return writeResponse(response); | 164 | return writeResponse(response); |
| 165 | }), | 165 | }), |
| 166 | send: (request, transferables) => { | 166 | send: (clientId, request, transferables) => { |
| 167 | if (request._tag === "Request") { | 167 | if (request._tag === "Request") { |
| 168 | trackRpcRequestSent(request.id, request.tag); | 168 | trackRpcRequestSent(request.id, request.tag); |
| 169 | } | 169 | } |
| 170 | return protocol.send(request, transferables); | 170 | return protocol.send(clientId, request, transferables); |
| 171 | }, | 171 | }, |
| 172 | }), | 172 | }), |
| 173 | ), | 173 | ), |
apps/web/src/rpc/serverState.test.ts+7-7| ... | @@ -52,7 +52,7 @@ const defaultProviders: ReadonlyArray<ServerProvider> = [ | ... | @@ -52,7 +52,7 @@ const defaultProviders: ReadonlyArray<ServerProvider> = [ |
| 52 | ]; | 52 | ]; |
| 53 | 53 | ||
| 54 | const baseEnvironment = { | 54 | const baseEnvironment = { |
| 55 | environmentId: EnvironmentId.makeUnsafe("environment-local"), | 55 | environmentId: EnvironmentId.make("environment-local"), |
| 56 | label: "Local environment", | 56 | label: "Local environment", |
| 57 | platform: { | 57 | platform: { |
| 58 | os: "darwin" as const, | 58 | os: "darwin" as const, |
| ... | @@ -217,8 +217,8 @@ describe("serverState", () => { | ... | @@ -217,8 +217,8 @@ describe("serverState", () => { |
| 217 | environment: baseEnvironment, | 217 | environment: baseEnvironment, |
| 218 | cwd: "/tmp/workspace", | 218 | cwd: "/tmp/workspace", |
| 219 | projectName: "t3-code", | 219 | projectName: "t3-code", |
| 220 | bootstrapProjectId: ProjectId.makeUnsafe("project-1"), | 220 | bootstrapProjectId: ProjectId.make("project-1"), |
| 221 | bootstrapThreadId: ThreadId.makeUnsafe("thread-1"), | 221 | bootstrapThreadId: ThreadId.make("thread-1"), |
| 222 | }, | 222 | }, |
| 223 | }); | 223 | }); |
| 224 | 224 | ||
| ... | @@ -226,8 +226,8 @@ describe("serverState", () => { | ... | @@ -226,8 +226,8 @@ describe("serverState", () => { |
| 226 | environment: baseEnvironment, | 226 | environment: baseEnvironment, |
| 227 | cwd: "/tmp/workspace", | 227 | cwd: "/tmp/workspace", |
| 228 | projectName: "t3-code", | 228 | projectName: "t3-code", |
| 229 | bootstrapProjectId: ProjectId.makeUnsafe("project-1"), | 229 | bootstrapProjectId: ProjectId.make("project-1"), |
| 230 | bootstrapThreadId: ThreadId.makeUnsafe("thread-1"), | 230 | bootstrapThreadId: ThreadId.make("thread-1"), |
| 231 | }); | 231 | }); |
| 232 | 232 | ||
| 233 | const lateListener = vi.fn(); | 233 | const lateListener = vi.fn(); |
| ... | @@ -236,8 +236,8 @@ describe("serverState", () => { | ... | @@ -236,8 +236,8 @@ describe("serverState", () => { |
| 236 | environment: baseEnvironment, | 236 | environment: baseEnvironment, |
| 237 | cwd: "/tmp/workspace", | 237 | cwd: "/tmp/workspace", |
| 238 | projectName: "t3-code", | 238 | projectName: "t3-code", |
| 239 | bootstrapProjectId: ProjectId.makeUnsafe("project-1"), | 239 | bootstrapProjectId: ProjectId.make("project-1"), |
| 240 | bootstrapThreadId: ThreadId.makeUnsafe("thread-1"), | 240 | bootstrapThreadId: ThreadId.make("thread-1"), |
| 241 | }); | 241 | }); |
| 242 | 242 | ||
| 243 | unsubscribeLate(); | 243 | unsubscribeLate(); |
apps/web/src/session-logic.test.ts+43-43| ... | @@ -35,13 +35,13 @@ function makeActivity(overrides: { | ... | @@ -35,13 +35,13 @@ function makeActivity(overrides: { |
| 35 | }): OrchestrationThreadActivity { | 35 | }): OrchestrationThreadActivity { |
| 36 | const payload = overrides.payload ?? {}; | 36 | const payload = overrides.payload ?? {}; |
| 37 | return { | 37 | return { |
| 38 | id: EventId.makeUnsafe(overrides.id ?? crypto.randomUUID()), | 38 | id: EventId.make(overrides.id ?? crypto.randomUUID()), |
| 39 | createdAt: overrides.createdAt ?? "2026-02-23T00:00:00.000Z", | 39 | createdAt: overrides.createdAt ?? "2026-02-23T00:00:00.000Z", |
| 40 | kind: overrides.kind ?? "tool.started", | 40 | kind: overrides.kind ?? "tool.started", |
| 41 | summary: overrides.summary ?? "Tool call", | 41 | summary: overrides.summary ?? "Tool call", |
| 42 | tone: overrides.tone ?? "tool", | 42 | tone: overrides.tone ?? "tool", |
| 43 | payload, | 43 | payload, |
| 44 | turnId: overrides.turnId ? TurnId.makeUnsafe(overrides.turnId) : null, | 44 | turnId: overrides.turnId ? TurnId.make(overrides.turnId) : null, |
| 45 | ...(overrides.sequence !== undefined ? { sequence: overrides.sequence } : {}), | 45 | ...(overrides.sequence !== undefined ? { sequence: overrides.sequence } : {}), |
| 46 | }; | 46 | }; |
| 47 | } | 47 | } |
| ... | @@ -336,7 +336,7 @@ describe("deriveActivePlanState", () => { | ... | @@ -336,7 +336,7 @@ describe("deriveActivePlanState", () => { |
| 336 | }), | 336 | }), |
| 337 | ]; | 337 | ]; |
| 338 | 338 | ||
| 339 | expect(deriveActivePlanState(activities, TurnId.makeUnsafe("turn-1"))).toEqual({ | 339 | expect(deriveActivePlanState(activities, TurnId.make("turn-1"))).toEqual({ |
| 340 | createdAt: "2026-02-23T00:00:02.000Z", | 340 | createdAt: "2026-02-23T00:00:02.000Z", |
| 341 | turnId: "turn-1", | 341 | turnId: "turn-1", |
| 342 | explanation: "Refined plan", | 342 | explanation: "Refined plan", |
| ... | @@ -352,7 +352,7 @@ describe("findLatestProposedPlan", () => { | ... | @@ -352,7 +352,7 @@ describe("findLatestProposedPlan", () => { |
| 352 | [ | 352 | [ |
| 353 | { | 353 | { |
| 354 | id: "plan:thread-1:turn:turn-1", | 354 | id: "plan:thread-1:turn:turn-1", |
| 355 | turnId: TurnId.makeUnsafe("turn-1"), | 355 | turnId: TurnId.make("turn-1"), |
| 356 | planMarkdown: "# Older", | 356 | planMarkdown: "# Older", |
| 357 | implementedAt: null, | 357 | implementedAt: null, |
| 358 | implementationThreadId: null, | 358 | implementationThreadId: null, |
| ... | @@ -361,7 +361,7 @@ describe("findLatestProposedPlan", () => { | ... | @@ -361,7 +361,7 @@ describe("findLatestProposedPlan", () => { |
| 361 | }, | 361 | }, |
| 362 | { | 362 | { |
| 363 | id: "plan:thread-1:turn:turn-1", | 363 | id: "plan:thread-1:turn:turn-1", |
| 364 | turnId: TurnId.makeUnsafe("turn-1"), | 364 | turnId: TurnId.make("turn-1"), |
| 365 | planMarkdown: "# Latest", | 365 | planMarkdown: "# Latest", |
| 366 | implementedAt: null, | 366 | implementedAt: null, |
| 367 | implementationThreadId: null, | 367 | implementationThreadId: null, |
| ... | @@ -370,7 +370,7 @@ describe("findLatestProposedPlan", () => { | ... | @@ -370,7 +370,7 @@ describe("findLatestProposedPlan", () => { |
| 370 | }, | 370 | }, |
| 371 | { | 371 | { |
| 372 | id: "plan:thread-1:turn:turn-2", | 372 | id: "plan:thread-1:turn:turn-2", |
| 373 | turnId: TurnId.makeUnsafe("turn-2"), | 373 | turnId: TurnId.make("turn-2"), |
| 374 | planMarkdown: "# Different turn", | 374 | planMarkdown: "# Different turn", |
| 375 | implementedAt: null, | 375 | implementedAt: null, |
| 376 | implementationThreadId: null, | 376 | implementationThreadId: null, |
| ... | @@ -378,7 +378,7 @@ describe("findLatestProposedPlan", () => { | ... | @@ -378,7 +378,7 @@ describe("findLatestProposedPlan", () => { |
| 378 | updatedAt: "2026-02-23T00:00:03.000Z", | 378 | updatedAt: "2026-02-23T00:00:03.000Z", |
| 379 | }, | 379 | }, |
| 380 | ], | 380 | ], |
| 381 | TurnId.makeUnsafe("turn-1"), | 381 | TurnId.make("turn-1"), |
| 382 | ), | 382 | ), |
| 383 | ).toEqual({ | 383 | ).toEqual({ |
| 384 | id: "plan:thread-1:turn:turn-1", | 384 | id: "plan:thread-1:turn:turn-1", |
| ... | @@ -396,7 +396,7 @@ describe("findLatestProposedPlan", () => { | ... | @@ -396,7 +396,7 @@ describe("findLatestProposedPlan", () => { |
| 396 | [ | 396 | [ |
| 397 | { | 397 | { |
| 398 | id: "plan:thread-1:turn:turn-1", | 398 | id: "plan:thread-1:turn:turn-1", |
| 399 | turnId: TurnId.makeUnsafe("turn-1"), | 399 | turnId: TurnId.make("turn-1"), |
| 400 | planMarkdown: "# First", | 400 | planMarkdown: "# First", |
| 401 | implementedAt: null, | 401 | implementedAt: null, |
| 402 | implementationThreadId: null, | 402 | implementationThreadId: null, |
| ... | @@ -405,7 +405,7 @@ describe("findLatestProposedPlan", () => { | ... | @@ -405,7 +405,7 @@ describe("findLatestProposedPlan", () => { |
| 405 | }, | 405 | }, |
| 406 | { | 406 | { |
| 407 | id: "plan:thread-1:turn:turn-2", | 407 | id: "plan:thread-1:turn:turn-2", |
| 408 | turnId: TurnId.makeUnsafe("turn-2"), | 408 | turnId: TurnId.make("turn-2"), |
| 409 | planMarkdown: "# Latest", | 409 | planMarkdown: "# Latest", |
| 410 | implementedAt: null, | 410 | implementedAt: null, |
| 411 | implementationThreadId: null, | 411 | implementationThreadId: null, |
| ... | @@ -425,7 +425,7 @@ describe("hasActionableProposedPlan", () => { | ... | @@ -425,7 +425,7 @@ describe("hasActionableProposedPlan", () => { |
| 425 | expect( | 425 | expect( |
| 426 | hasActionableProposedPlan({ | 426 | hasActionableProposedPlan({ |
| 427 | id: "plan-1", | 427 | id: "plan-1", |
| 428 | turnId: TurnId.makeUnsafe("turn-1"), | 428 | turnId: TurnId.make("turn-1"), |
| 429 | planMarkdown: "# Plan", | 429 | planMarkdown: "# Plan", |
| 430 | implementedAt: null, | 430 | implementedAt: null, |
| 431 | implementationThreadId: null, | 431 | implementationThreadId: null, |
| ... | @@ -439,10 +439,10 @@ describe("hasActionableProposedPlan", () => { | ... | @@ -439,10 +439,10 @@ describe("hasActionableProposedPlan", () => { |
| 439 | expect( | 439 | expect( |
| 440 | hasActionableProposedPlan({ | 440 | hasActionableProposedPlan({ |
| 441 | id: "plan-1", | 441 | id: "plan-1", |
| 442 | turnId: TurnId.makeUnsafe("turn-1"), | 442 | turnId: TurnId.make("turn-1"), |
| 443 | planMarkdown: "# Plan", | 443 | planMarkdown: "# Plan", |
| 444 | implementedAt: "2026-02-23T00:00:02.000Z", | 444 | implementedAt: "2026-02-23T00:00:02.000Z", |
| 445 | implementationThreadId: ThreadId.makeUnsafe("thread-implement"), | 445 | implementationThreadId: ThreadId.make("thread-implement"), |
| 446 | createdAt: "2026-02-23T00:00:00.000Z", | 446 | createdAt: "2026-02-23T00:00:00.000Z", |
| 447 | updatedAt: "2026-02-23T00:00:02.000Z", | 447 | updatedAt: "2026-02-23T00:00:02.000Z", |
| 448 | }), | 448 | }), |
| ... | @@ -456,25 +456,25 @@ describe("findSidebarProposedPlan", () => { | ... | @@ -456,25 +456,25 @@ describe("findSidebarProposedPlan", () => { |
| 456 | findSidebarProposedPlan({ | 456 | findSidebarProposedPlan({ |
| 457 | threads: [ | 457 | threads: [ |
| 458 | { | 458 | { |
| 459 | id: ThreadId.makeUnsafe("thread-1"), | 459 | id: ThreadId.make("thread-1"), |
| 460 | proposedPlans: [ | 460 | proposedPlans: [ |
| 461 | { | 461 | { |
| 462 | id: "plan-1", | 462 | id: "plan-1", |
| 463 | turnId: TurnId.makeUnsafe("turn-plan"), | 463 | turnId: TurnId.make("turn-plan"), |
| 464 | planMarkdown: "# Source plan", | 464 | planMarkdown: "# Source plan", |
| 465 | implementedAt: "2026-02-23T00:00:03.000Z", | 465 | implementedAt: "2026-02-23T00:00:03.000Z", |
| 466 | implementationThreadId: ThreadId.makeUnsafe("thread-2"), | 466 | implementationThreadId: ThreadId.make("thread-2"), |
| 467 | createdAt: "2026-02-23T00:00:01.000Z", | 467 | createdAt: "2026-02-23T00:00:01.000Z", |
| 468 | updatedAt: "2026-02-23T00:00:02.000Z", | 468 | updatedAt: "2026-02-23T00:00:02.000Z", |
| 469 | }, | 469 | }, |
| 470 | ], | 470 | ], |
| 471 | }, | 471 | }, |
| 472 | { | 472 | { |
| 473 | id: ThreadId.makeUnsafe("thread-2"), | 473 | id: ThreadId.make("thread-2"), |
| 474 | proposedPlans: [ | 474 | proposedPlans: [ |
| 475 | { | 475 | { |
| 476 | id: "plan-2", | 476 | id: "plan-2", |
| 477 | turnId: TurnId.makeUnsafe("turn-other"), | 477 | turnId: TurnId.make("turn-other"), |
| 478 | planMarkdown: "# Latest elsewhere", | 478 | planMarkdown: "# Latest elsewhere", |
| 479 | implementedAt: null, | 479 | implementedAt: null, |
| 480 | implementationThreadId: null, | 480 | implementationThreadId: null, |
| ... | @@ -485,14 +485,14 @@ describe("findSidebarProposedPlan", () => { | ... | @@ -485,14 +485,14 @@ describe("findSidebarProposedPlan", () => { |
| 485 | }, | 485 | }, |
| 486 | ], | 486 | ], |
| 487 | latestTurn: { | 487 | latestTurn: { |
| 488 | turnId: TurnId.makeUnsafe("turn-implementation"), | 488 | turnId: TurnId.make("turn-implementation"), |
| 489 | sourceProposedPlan: { | 489 | sourceProposedPlan: { |
| 490 | threadId: ThreadId.makeUnsafe("thread-1"), | 490 | threadId: ThreadId.make("thread-1"), |
| 491 | planId: "plan-1", | 491 | planId: "plan-1", |
| 492 | }, | 492 | }, |
| 493 | }, | 493 | }, |
| 494 | latestTurnSettled: false, | 494 | latestTurnSettled: false, |
| 495 | threadId: ThreadId.makeUnsafe("thread-1"), | 495 | threadId: ThreadId.make("thread-1"), |
| 496 | }), | 496 | }), |
| 497 | ).toEqual({ | 497 | ).toEqual({ |
| 498 | id: "plan-1", | 498 | id: "plan-1", |
| ... | @@ -510,11 +510,11 @@ describe("findSidebarProposedPlan", () => { | ... | @@ -510,11 +510,11 @@ describe("findSidebarProposedPlan", () => { |
| 510 | findSidebarProposedPlan({ | 510 | findSidebarProposedPlan({ |
| 511 | threads: [ | 511 | threads: [ |
| 512 | { | 512 | { |
| 513 | id: ThreadId.makeUnsafe("thread-1"), | 513 | id: ThreadId.make("thread-1"), |
| 514 | proposedPlans: [ | 514 | proposedPlans: [ |
| 515 | { | 515 | { |
| 516 | id: "plan-1", | 516 | id: "plan-1", |
| 517 | turnId: TurnId.makeUnsafe("turn-plan"), | 517 | turnId: TurnId.make("turn-plan"), |
| 518 | planMarkdown: "# Older", | 518 | planMarkdown: "# Older", |
| 519 | implementedAt: null, | 519 | implementedAt: null, |
| 520 | implementationThreadId: null, | 520 | implementationThreadId: null, |
| ... | @@ -523,7 +523,7 @@ describe("findSidebarProposedPlan", () => { | ... | @@ -523,7 +523,7 @@ describe("findSidebarProposedPlan", () => { |
| 523 | }, | 523 | }, |
| 524 | { | 524 | { |
| 525 | id: "plan-2", | 525 | id: "plan-2", |
| 526 | turnId: TurnId.makeUnsafe("turn-latest"), | 526 | turnId: TurnId.make("turn-latest"), |
| 527 | planMarkdown: "# Latest", | 527 | planMarkdown: "# Latest", |
| 528 | implementedAt: null, | 528 | implementedAt: null, |
| 529 | implementationThreadId: null, | 529 | implementationThreadId: null, |
| ... | @@ -534,14 +534,14 @@ describe("findSidebarProposedPlan", () => { | ... | @@ -534,14 +534,14 @@ describe("findSidebarProposedPlan", () => { |
| 534 | }, | 534 | }, |
| 535 | ], | 535 | ], |
| 536 | latestTurn: { | 536 | latestTurn: { |
| 537 | turnId: TurnId.makeUnsafe("turn-implementation"), | 537 | turnId: TurnId.make("turn-implementation"), |
| 538 | sourceProposedPlan: { | 538 | sourceProposedPlan: { |
| 539 | threadId: ThreadId.makeUnsafe("thread-1"), | 539 | threadId: ThreadId.make("thread-1"), |
| 540 | planId: "plan-1", | 540 | planId: "plan-1", |
| 541 | }, | 541 | }, |
| 542 | }, | 542 | }, |
| 543 | latestTurnSettled: true, | 543 | latestTurnSettled: true, |
| 544 | threadId: ThreadId.makeUnsafe("thread-1"), | 544 | threadId: ThreadId.make("thread-1"), |
| 545 | })?.planMarkdown, | 545 | })?.planMarkdown, |
| 546 | ).toBe("# Latest"); | 546 | ).toBe("# Latest"); |
| 547 | }); | 547 | }); |
| ... | @@ -609,7 +609,7 @@ describe("deriveWorkLogEntries", () => { | ... | @@ -609,7 +609,7 @@ describe("deriveWorkLogEntries", () => { |
| 609 | makeActivity({ id: "no-turn", summary: "Checkpoint captured", tone: "info" }), | 609 | makeActivity({ id: "no-turn", summary: "Checkpoint captured", tone: "info" }), |
| 610 | ]; | 610 | ]; |
| 611 | 611 | ||
| 612 | const entries = deriveWorkLogEntries(activities, TurnId.makeUnsafe("turn-2")); | 612 | const entries = deriveWorkLogEntries(activities, TurnId.make("turn-2")); |
| 613 | expect(entries.map((entry) => entry.id)).toEqual(["turn-2"]); | 613 | expect(entries.map((entry) => entry.id)).toEqual(["turn-2"]); |
| 614 | }); | 614 | }); |
| 615 | 615 | ||
| ... | @@ -1022,7 +1022,7 @@ describe("deriveTimelineEntries", () => { | ... | @@ -1022,7 +1022,7 @@ describe("deriveTimelineEntries", () => { |
| 1022 | const entries = deriveTimelineEntries( | 1022 | const entries = deriveTimelineEntries( |
| 1023 | [ | 1023 | [ |
| 1024 | { | 1024 | { |
| 1025 | id: MessageId.makeUnsafe("message-1"), | 1025 | id: MessageId.make("message-1"), |
| 1026 | role: "assistant", | 1026 | role: "assistant", |
| 1027 | text: "hello", | 1027 | text: "hello", |
| 1028 | createdAt: "2026-02-23T00:00:01.000Z", | 1028 | createdAt: "2026-02-23T00:00:01.000Z", |
| ... | @@ -1032,7 +1032,7 @@ describe("deriveTimelineEntries", () => { | ... | @@ -1032,7 +1032,7 @@ describe("deriveTimelineEntries", () => { |
| 1032 | [ | 1032 | [ |
| 1033 | { | 1033 | { |
| 1034 | id: "plan:thread-1:turn:turn-1", | 1034 | id: "plan:thread-1:turn:turn-1", |
| 1035 | turnId: TurnId.makeUnsafe("turn-1"), | 1035 | turnId: TurnId.make("turn-1"), |
| 1036 | planMarkdown: "# Ship it", | 1036 | planMarkdown: "# Ship it", |
| 1037 | implementedAt: null, | 1037 | implementedAt: null, |
| 1038 | implementationThreadId: null, | 1038 | implementationThreadId: null, |
| ... | @@ -1065,14 +1065,14 @@ describe("deriveTimelineEntries", () => { | ... | @@ -1065,14 +1065,14 @@ describe("deriveTimelineEntries", () => { |
| 1065 | const entries = deriveTimelineEntries( | 1065 | const entries = deriveTimelineEntries( |
| 1066 | [ | 1066 | [ |
| 1067 | { | 1067 | { |
| 1068 | id: MessageId.makeUnsafe("assistant-earlier"), | 1068 | id: MessageId.make("assistant-earlier"), |
| 1069 | role: "assistant", | 1069 | role: "assistant", |
| 1070 | text: "progress update", | 1070 | text: "progress update", |
| 1071 | createdAt: "2026-02-23T00:00:01.000Z", | 1071 | createdAt: "2026-02-23T00:00:01.000Z", |
| 1072 | streaming: false, | 1072 | streaming: false, |
| 1073 | }, | 1073 | }, |
| 1074 | { | 1074 | { |
| 1075 | id: MessageId.makeUnsafe("assistant-final"), | 1075 | id: MessageId.make("assistant-final"), |
| 1076 | role: "assistant", | 1076 | role: "assistant", |
| 1077 | text: "final answer", | 1077 | text: "final answer", |
| 1078 | createdAt: "2026-02-23T00:00:01.000Z", | 1078 | createdAt: "2026-02-23T00:00:01.000Z", |
| ... | @@ -1085,7 +1085,7 @@ describe("deriveTimelineEntries", () => { | ... | @@ -1085,7 +1085,7 @@ describe("deriveTimelineEntries", () => { |
| 1085 | 1085 | ||
| 1086 | expect( | 1086 | expect( |
| 1087 | deriveCompletionDividerBeforeEntryId(entries, { | 1087 | deriveCompletionDividerBeforeEntryId(entries, { |
| 1088 | assistantMessageId: MessageId.makeUnsafe("assistant-final"), | 1088 | assistantMessageId: MessageId.make("assistant-final"), |
| 1089 | startedAt: "2026-02-23T00:00:00.000Z", | 1089 | startedAt: "2026-02-23T00:00:00.000Z", |
| 1090 | completedAt: "2026-02-23T00:00:02.000Z", | 1090 | completedAt: "2026-02-23T00:00:02.000Z", |
| 1091 | }), | 1091 | }), |
| ... | @@ -1112,7 +1112,7 @@ describe("deriveWorkLogEntries context window handling", () => { | ... | @@ -1112,7 +1112,7 @@ describe("deriveWorkLogEntries context window handling", () => { |
| 1112 | tone: "tool", | 1112 | tone: "tool", |
| 1113 | }), | 1113 | }), |
| 1114 | ], | 1114 | ], |
| 1115 | TurnId.makeUnsafe("turn-1"), | 1115 | TurnId.make("turn-1"), |
| 1116 | ); | 1116 | ); |
| 1117 | 1117 | ||
| 1118 | expect(entries).toHaveLength(1); | 1118 | expect(entries).toHaveLength(1); |
| ... | @@ -1130,7 +1130,7 @@ describe("deriveWorkLogEntries context window handling", () => { | ... | @@ -1130,7 +1130,7 @@ describe("deriveWorkLogEntries context window handling", () => { |
| 1130 | tone: "info", | 1130 | tone: "info", |
| 1131 | }), | 1131 | }), |
| 1132 | ], | 1132 | ], |
| 1133 | TurnId.makeUnsafe("turn-1"), | 1133 | TurnId.make("turn-1"), |
| 1134 | ); | 1134 | ); |
| 1135 | 1135 | ||
| 1136 | expect(entries).toHaveLength(1); | 1136 | expect(entries).toHaveLength(1); |
| ... | @@ -1154,14 +1154,14 @@ describe("hasToolActivityForTurn", () => { | ... | @@ -1154,14 +1154,14 @@ describe("hasToolActivityForTurn", () => { |
| 1154 | makeActivity({ id: "info-1", turnId: "turn-2", kind: "turn.completed", tone: "info" }), | 1154 | makeActivity({ id: "info-1", turnId: "turn-2", kind: "turn.completed", tone: "info" }), |
| 1155 | ]; | 1155 | ]; |
| 1156 | 1156 | ||
| 1157 | expect(hasToolActivityForTurn(activities, TurnId.makeUnsafe("turn-1"))).toBe(true); | 1157 | expect(hasToolActivityForTurn(activities, TurnId.make("turn-1"))).toBe(true); |
| 1158 | expect(hasToolActivityForTurn(activities, TurnId.makeUnsafe("turn-2"))).toBe(false); | 1158 | expect(hasToolActivityForTurn(activities, TurnId.make("turn-2"))).toBe(false); |
| 1159 | }); | 1159 | }); |
| 1160 | }); | 1160 | }); |
| 1161 | 1161 | ||
| 1162 | describe("isLatestTurnSettled", () => { | 1162 | describe("isLatestTurnSettled", () => { |
| 1163 | const latestTurn = { | 1163 | const latestTurn = { |
| 1164 | turnId: TurnId.makeUnsafe("turn-1"), | 1164 | turnId: TurnId.make("turn-1"), |
| 1165 | startedAt: "2026-02-27T21:10:00.000Z", | 1165 | startedAt: "2026-02-27T21:10:00.000Z", |
| 1166 | completedAt: "2026-02-27T21:10:06.000Z", | 1166 | completedAt: "2026-02-27T21:10:06.000Z", |
| 1167 | } as const; | 1167 | } as const; |
| ... | @@ -1170,7 +1170,7 @@ describe("isLatestTurnSettled", () => { | ... | @@ -1170,7 +1170,7 @@ describe("isLatestTurnSettled", () => { |
| 1170 | expect( | 1170 | expect( |
| 1171 | isLatestTurnSettled(latestTurn, { | 1171 | isLatestTurnSettled(latestTurn, { |
| 1172 | orchestrationStatus: "running", | 1172 | orchestrationStatus: "running", |
| 1173 | activeTurnId: TurnId.makeUnsafe("turn-1"), | 1173 | activeTurnId: TurnId.make("turn-1"), |
| 1174 | }), | 1174 | }), |
| 1175 | ).toBe(false); | 1175 | ).toBe(false); |
| 1176 | }); | 1176 | }); |
| ... | @@ -1179,7 +1179,7 @@ describe("isLatestTurnSettled", () => { | ... | @@ -1179,7 +1179,7 @@ describe("isLatestTurnSettled", () => { |
| 1179 | expect( | 1179 | expect( |
| 1180 | isLatestTurnSettled(latestTurn, { | 1180 | isLatestTurnSettled(latestTurn, { |
| 1181 | orchestrationStatus: "running", | 1181 | orchestrationStatus: "running", |
| 1182 | activeTurnId: TurnId.makeUnsafe("turn-2"), | 1182 | activeTurnId: TurnId.make("turn-2"), |
| 1183 | }), | 1183 | }), |
| 1184 | ).toBe(false); | 1184 | ).toBe(false); |
| 1185 | }); | 1185 | }); |
| ... | @@ -1197,7 +1197,7 @@ describe("isLatestTurnSettled", () => { | ... | @@ -1197,7 +1197,7 @@ describe("isLatestTurnSettled", () => { |
| 1197 | expect( | 1197 | expect( |
| 1198 | isLatestTurnSettled( | 1198 | isLatestTurnSettled( |
| 1199 | { | 1199 | { |
| 1200 | turnId: TurnId.makeUnsafe("turn-1"), | 1200 | turnId: TurnId.make("turn-1"), |
| 1201 | startedAt: null, | 1201 | startedAt: null, |
| 1202 | completedAt: "2026-02-27T21:10:06.000Z", | 1202 | completedAt: "2026-02-27T21:10:06.000Z", |
| 1203 | }, | 1203 | }, |
| ... | @@ -1209,7 +1209,7 @@ describe("isLatestTurnSettled", () => { | ... | @@ -1209,7 +1209,7 @@ describe("isLatestTurnSettled", () => { |
| 1209 | 1209 | ||
| 1210 | describe("deriveActiveWorkStartedAt", () => { | 1210 | describe("deriveActiveWorkStartedAt", () => { |
| 1211 | const latestTurn = { | 1211 | const latestTurn = { |
| 1212 | turnId: TurnId.makeUnsafe("turn-1"), | 1212 | turnId: TurnId.make("turn-1"), |
| 1213 | startedAt: "2026-02-27T21:10:00.000Z", | 1213 | startedAt: "2026-02-27T21:10:00.000Z", |
| 1214 | completedAt: "2026-02-27T21:10:06.000Z", | 1214 | completedAt: "2026-02-27T21:10:06.000Z", |
| 1215 | } as const; | 1215 | } as const; |
| ... | @@ -1220,7 +1220,7 @@ describe("deriveActiveWorkStartedAt", () => { | ... | @@ -1220,7 +1220,7 @@ describe("deriveActiveWorkStartedAt", () => { |
| 1220 | latestTurn, | 1220 | latestTurn, |
| 1221 | { | 1221 | { |
| 1222 | orchestrationStatus: "running", | 1222 | orchestrationStatus: "running", |
| 1223 | activeTurnId: TurnId.makeUnsafe("turn-1"), | 1223 | activeTurnId: TurnId.make("turn-1"), |
| 1224 | }, | 1224 | }, |
| 1225 | "2026-02-27T21:11:00.000Z", | 1225 | "2026-02-27T21:11:00.000Z", |
| 1226 | ), | 1226 | ), |
| ... | @@ -1244,7 +1244,7 @@ describe("deriveActiveWorkStartedAt", () => { | ... | @@ -1244,7 +1244,7 @@ describe("deriveActiveWorkStartedAt", () => { |
| 1244 | expect( | 1244 | expect( |
| 1245 | deriveActiveWorkStartedAt( | 1245 | deriveActiveWorkStartedAt( |
| 1246 | { | 1246 | { |
| 1247 | turnId: TurnId.makeUnsafe("turn-1"), | 1247 | turnId: TurnId.make("turn-1"), |
| 1248 | startedAt: "2026-02-27T21:10:00.000Z", | 1248 | startedAt: "2026-02-27T21:10:00.000Z", |
| 1249 | completedAt: "2026-02-27T21:10:06.000Z", | 1249 | completedAt: "2026-02-27T21:10:06.000Z", |
| 1250 | }, | 1250 | }, |
apps/web/src/session-logic.ts+2-2| ... | @@ -193,7 +193,7 @@ export function derivePendingApprovals( | ... | @@ -193,7 +193,7 @@ export function derivePendingApprovals( |
| 193 | : null; | 193 | : null; |
| 194 | const requestId = | 194 | const requestId = |
| 195 | payload && typeof payload.requestId === "string" | 195 | payload && typeof payload.requestId === "string" |
| 196 | ? ApprovalRequestId.makeUnsafe(payload.requestId) | 196 | ? ApprovalRequestId.make(payload.requestId) |
| 197 | : null; | 197 | : null; |
| 198 | const requestKind = | 198 | const requestKind = |
| 199 | payload && | 199 | payload && |
| ... | @@ -299,7 +299,7 @@ export function derivePendingUserInputs( | ... | @@ -299,7 +299,7 @@ export function derivePendingUserInputs( |
| 299 | : null; | 299 | : null; |
| 300 | const requestId = | 300 | const requestId = |
| 301 | payload && typeof payload.requestId === "string" | 301 | payload && typeof payload.requestId === "string" |
| 302 | ? ApprovalRequestId.makeUnsafe(payload.requestId) | 302 | ? ApprovalRequestId.make(payload.requestId) |
| 303 | : null; | 303 | : null; |
| 304 | const detail = payload && typeof payload.detail === "string" ? payload.detail : undefined; | 304 | const detail = payload && typeof payload.detail === "string" ? payload.detail : undefined; |
| 305 | 305 |
apps/web/src/store.test.ts+76-76| ... | @@ -26,8 +26,8 @@ import { | ... | @@ -26,8 +26,8 @@ import { |
| 26 | } from "./store"; | 26 | } from "./store"; |
| 27 | import { DEFAULT_INTERACTION_MODE, DEFAULT_RUNTIME_MODE, type Thread } from "./types"; | 27 | import { DEFAULT_INTERACTION_MODE, DEFAULT_RUNTIME_MODE, type Thread } from "./types"; |
| 28 | 28 | ||
| 29 | const localEnvironmentId = EnvironmentId.makeUnsafe("environment-local"); | 29 | const localEnvironmentId = EnvironmentId.make("environment-local"); |
| 30 | const remoteEnvironmentId = EnvironmentId.makeUnsafe("environment-remote"); | 30 | const remoteEnvironmentId = EnvironmentId.make("environment-remote"); |
| 31 | 31 | ||
| 32 | function withActiveEnvironmentState( | 32 | function withActiveEnvironmentState( |
| 33 | environmentState: EnvironmentState, | 33 | environmentState: EnvironmentState, |
| ... | @@ -59,10 +59,10 @@ function withActiveEnvironmentState( | ... | @@ -59,10 +59,10 @@ function withActiveEnvironmentState( |
| 59 | 59 | ||
| 60 | function makeThread(overrides: Partial<Thread> = {}): Thread { | 60 | function makeThread(overrides: Partial<Thread> = {}): Thread { |
| 61 | return { | 61 | return { |
| 62 | id: ThreadId.makeUnsafe("thread-1"), | 62 | id: ThreadId.make("thread-1"), |
| 63 | environmentId: localEnvironmentId, | 63 | environmentId: localEnvironmentId, |
| 64 | codexThreadId: null, | 64 | codexThreadId: null, |
| 65 | projectId: ProjectId.makeUnsafe("project-1"), | 65 | projectId: ProjectId.make("project-1"), |
| 66 | title: "Thread", | 66 | title: "Thread", |
| 67 | modelSelection: { | 67 | modelSelection: { |
| 68 | provider: "codex", | 68 | provider: "codex", |
| ... | @@ -86,7 +86,7 @@ function makeThread(overrides: Partial<Thread> = {}): Thread { | ... | @@ -86,7 +86,7 @@ function makeThread(overrides: Partial<Thread> = {}): Thread { |
| 86 | } | 86 | } |
| 87 | 87 | ||
| 88 | function makeState(thread: Thread): AppState { | 88 | function makeState(thread: Thread): AppState { |
| 89 | const projectId = ProjectId.makeUnsafe("project-1"); | 89 | const projectId = ProjectId.make("project-1"); |
| 90 | const project = { | 90 | const project = { |
| 91 | id: projectId, | 91 | id: projectId, |
| 92 | environmentId: thread.environmentId, | 92 | environmentId: thread.environmentId, |
| ... | @@ -226,14 +226,14 @@ function makeEvent<T extends OrchestrationEvent["type"]>( | ... | @@ -226,14 +226,14 @@ function makeEvent<T extends OrchestrationEvent["type"]>( |
| 226 | const sequence = overrides.sequence ?? 1; | 226 | const sequence = overrides.sequence ?? 1; |
| 227 | return { | 227 | return { |
| 228 | sequence, | 228 | sequence, |
| 229 | eventId: EventId.makeUnsafe(`event-${sequence}`), | 229 | eventId: EventId.make(`event-${sequence}`), |
| 230 | aggregateKind: "thread", | 230 | aggregateKind: "thread", |
| 231 | aggregateId: | 231 | aggregateId: |
| 232 | "threadId" in payload | 232 | "threadId" in payload |
| 233 | ? payload.threadId | 233 | ? payload.threadId |
| 234 | : "projectId" in payload | 234 | : "projectId" in payload |
| 235 | ? payload.projectId | 235 | ? payload.projectId |
| 236 | : ProjectId.makeUnsafe("project-1"), | 236 | : ProjectId.make("project-1"), |
| 237 | occurredAt: "2026-02-27T00:00:00.000Z", | 237 | occurredAt: "2026-02-27T00:00:00.000Z", |
| 238 | commandId: null, | 238 | commandId: null, |
| 239 | causationEventId: null, | 239 | causationEventId: null, |
| ... | @@ -247,8 +247,8 @@ function makeEvent<T extends OrchestrationEvent["type"]>( | ... | @@ -247,8 +247,8 @@ function makeEvent<T extends OrchestrationEvent["type"]>( |
| 247 | 247 | ||
| 248 | function makeReadModelThread(overrides: Partial<OrchestrationReadModel["threads"][number]>) { | 248 | function makeReadModelThread(overrides: Partial<OrchestrationReadModel["threads"][number]>) { |
| 249 | return { | 249 | return { |
| 250 | id: ThreadId.makeUnsafe("thread-1"), | 250 | id: ThreadId.make("thread-1"), |
| 251 | projectId: ProjectId.makeUnsafe("project-1"), | 251 | projectId: ProjectId.make("project-1"), |
| 252 | title: "Thread", | 252 | title: "Thread", |
| 253 | modelSelection: { | 253 | modelSelection: { |
| 254 | provider: "codex", | 254 | provider: "codex", |
| ... | @@ -278,7 +278,7 @@ function makeReadModel(thread: OrchestrationReadModel["threads"][number]): Orche | ... | @@ -278,7 +278,7 @@ function makeReadModel(thread: OrchestrationReadModel["threads"][number]): Orche |
| 278 | updatedAt: "2026-02-27T00:00:00.000Z", | 278 | updatedAt: "2026-02-27T00:00:00.000Z", |
| 279 | projects: [ | 279 | projects: [ |
| 280 | { | 280 | { |
| 281 | id: ProjectId.makeUnsafe("project-1"), | 281 | id: ProjectId.make("project-1"), |
| 282 | title: "Project", | 282 | title: "Project", |
| 283 | workspaceRoot: "/tmp/project", | 283 | workspaceRoot: "/tmp/project", |
| 284 | defaultModelSelection: { | 284 | defaultModelSelection: { |
| ... | @@ -299,7 +299,7 @@ function makeReadModelProject( | ... | @@ -299,7 +299,7 @@ function makeReadModelProject( |
| 299 | overrides: Partial<OrchestrationReadModel["projects"][number]>, | 299 | overrides: Partial<OrchestrationReadModel["projects"][number]>, |
| 300 | ): OrchestrationReadModel["projects"][number] { | 300 | ): OrchestrationReadModel["projects"][number] { |
| 301 | return { | 301 | return { |
| 302 | id: ProjectId.makeUnsafe("project-1"), | 302 | id: ProjectId.make("project-1"), |
| 303 | title: "Project", | 303 | title: "Project", |
| 304 | workspaceRoot: "/tmp/project", | 304 | workspaceRoot: "/tmp/project", |
| 305 | defaultModelSelection: { | 305 | defaultModelSelection: { |
| ... | @@ -316,7 +316,7 @@ function makeReadModelProject( | ... | @@ -316,7 +316,7 @@ function makeReadModelProject( |
| 316 | 316 | ||
| 317 | describe("setThreadBranch", () => { | 317 | describe("setThreadBranch", () => { |
| 318 | it("updates only the scoped thread environment", () => { | 318 | it("updates only the scoped thread environment", () => { |
| 319 | const sharedThreadId = ThreadId.makeUnsafe("thread-shared"); | 319 | const sharedThreadId = ThreadId.make("thread-shared"); |
| 320 | const localThread = makeThread({ | 320 | const localThread = makeThread({ |
| 321 | id: sharedThreadId, | 321 | id: sharedThreadId, |
| 322 | environmentId: localEnvironmentId, | 322 | environmentId: localEnvironmentId, |
| ... | @@ -397,7 +397,7 @@ describe("store read model sync", () => { | ... | @@ -397,7 +397,7 @@ describe("store read model sync", () => { |
| 397 | model: "sonnet", | 397 | model: "sonnet", |
| 398 | }, | 398 | }, |
| 399 | session: { | 399 | session: { |
| 400 | threadId: ThreadId.makeUnsafe("thread-1"), | 400 | threadId: ThreadId.make("thread-1"), |
| 401 | status: "ready", | 401 | status: "ready", |
| 402 | providerName: "claudeAgent", | 402 | providerName: "claudeAgent", |
| 403 | runtimeMode: "approval-required", | 403 | runtimeMode: "approval-required", |
| ... | @@ -444,9 +444,9 @@ describe("store read model sync", () => { | ... | @@ -444,9 +444,9 @@ describe("store read model sync", () => { |
| 444 | }); | 444 | }); |
| 445 | 445 | ||
| 446 | it("replaces projects using snapshot order during recovery", () => { | 446 | it("replaces projects using snapshot order during recovery", () => { |
| 447 | const project1 = ProjectId.makeUnsafe("project-1"); | 447 | const project1 = ProjectId.make("project-1"); |
| 448 | const project2 = ProjectId.makeUnsafe("project-2"); | 448 | const project2 = ProjectId.make("project-2"); |
| 449 | const project3 = ProjectId.makeUnsafe("project-3"); | 449 | const project3 = ProjectId.make("project-3"); |
| 450 | const initialState: AppState = makeEmptyState({ | 450 | const initialState: AppState = makeEmptyState({ |
| 451 | projectIds: [project2, project1], | 451 | projectIds: [project2, project1], |
| 452 | projectById: { | 452 | projectById: { |
| ... | @@ -516,7 +516,7 @@ describe("incremental orchestration updates", () => { | ... | @@ -516,7 +516,7 @@ describe("incremental orchestration updates", () => { |
| 516 | const next = applyOrchestrationEvent( | 516 | const next = applyOrchestrationEvent( |
| 517 | state, | 517 | state, |
| 518 | makeEvent("thread.meta-updated", { | 518 | makeEvent("thread.meta-updated", { |
| 519 | threadId: ThreadId.makeUnsafe("thread-1"), | 519 | threadId: ThreadId.make("thread-1"), |
| 520 | title: "Updated title", | 520 | title: "Updated title", |
| 521 | updatedAt: "2026-02-27T00:00:01.000Z", | 521 | updatedAt: "2026-02-27T00:00:01.000Z", |
| 522 | }), | 522 | }), |
| ... | @@ -533,7 +533,7 @@ describe("incremental orchestration updates", () => { | ... | @@ -533,7 +533,7 @@ describe("incremental orchestration updates", () => { |
| 533 | const nextAfterProjectDelete = applyOrchestrationEvent( | 533 | const nextAfterProjectDelete = applyOrchestrationEvent( |
| 534 | state, | 534 | state, |
| 535 | makeEvent("project.deleted", { | 535 | makeEvent("project.deleted", { |
| 536 | projectId: ProjectId.makeUnsafe("project-missing"), | 536 | projectId: ProjectId.make("project-missing"), |
| 537 | deletedAt: "2026-02-27T00:00:01.000Z", | 537 | deletedAt: "2026-02-27T00:00:01.000Z", |
| 538 | }), | 538 | }), |
| 539 | localEnvironmentId, | 539 | localEnvironmentId, |
| ... | @@ -541,7 +541,7 @@ describe("incremental orchestration updates", () => { | ... | @@ -541,7 +541,7 @@ describe("incremental orchestration updates", () => { |
| 541 | const nextAfterThreadDelete = applyOrchestrationEvent( | 541 | const nextAfterThreadDelete = applyOrchestrationEvent( |
| 542 | state, | 542 | state, |
| 543 | makeEvent("thread.deleted", { | 543 | makeEvent("thread.deleted", { |
| 544 | threadId: ThreadId.makeUnsafe("thread-missing"), | 544 | threadId: ThreadId.make("thread-missing"), |
| 545 | deletedAt: "2026-02-27T00:00:01.000Z", | 545 | deletedAt: "2026-02-27T00:00:01.000Z", |
| 546 | }), | 546 | }), |
| 547 | localEnvironmentId, | 547 | localEnvironmentId, |
| ... | @@ -552,8 +552,8 @@ describe("incremental orchestration updates", () => { | ... | @@ -552,8 +552,8 @@ describe("incremental orchestration updates", () => { |
| 552 | }); | 552 | }); |
| 553 | 553 | ||
| 554 | it("reuses an existing project row when project.created arrives with a new id for the same cwd", () => { | 554 | it("reuses an existing project row when project.created arrives with a new id for the same cwd", () => { |
| 555 | const originalProjectId = ProjectId.makeUnsafe("project-1"); | 555 | const originalProjectId = ProjectId.make("project-1"); |
| 556 | const recreatedProjectId = ProjectId.makeUnsafe("project-2"); | 556 | const recreatedProjectId = ProjectId.make("project-2"); |
| 557 | const state: AppState = makeEmptyState({ | 557 | const state: AppState = makeEmptyState({ |
| 558 | projectIds: [originalProjectId], | 558 | projectIds: [originalProjectId], |
| 559 | projectById: { | 559 | projectById: { |
| ... | @@ -602,9 +602,9 @@ describe("incremental orchestration updates", () => { | ... | @@ -602,9 +602,9 @@ describe("incremental orchestration updates", () => { |
| 602 | }); | 602 | }); |
| 603 | 603 | ||
| 604 | it("removes stale project index entries when thread.created recreates a thread under a new project", () => { | 604 | it("removes stale project index entries when thread.created recreates a thread under a new project", () => { |
| 605 | const originalProjectId = ProjectId.makeUnsafe("project-1"); | 605 | const originalProjectId = ProjectId.make("project-1"); |
| 606 | const recreatedProjectId = ProjectId.makeUnsafe("project-2"); | 606 | const recreatedProjectId = ProjectId.make("project-2"); |
| 607 | const threadId = ThreadId.makeUnsafe("thread-1"); | 607 | const threadId = ThreadId.make("thread-1"); |
| 608 | const thread = makeThread({ | 608 | const thread = makeThread({ |
| 609 | id: threadId, | 609 | id: threadId, |
| 610 | projectId: originalProjectId, | 610 | projectId: originalProjectId, |
| ... | @@ -671,20 +671,20 @@ describe("incremental orchestration updates", () => { | ... | @@ -671,20 +671,20 @@ describe("incremental orchestration updates", () => { |
| 671 | 671 | ||
| 672 | it("updates only the affected thread for message events", () => { | 672 | it("updates only the affected thread for message events", () => { |
| 673 | const thread1 = makeThread({ | 673 | const thread1 = makeThread({ |
| 674 | id: ThreadId.makeUnsafe("thread-1"), | 674 | id: ThreadId.make("thread-1"), |
| 675 | messages: [ | 675 | messages: [ |
| 676 | { | 676 | { |
| 677 | id: MessageId.makeUnsafe("message-1"), | 677 | id: MessageId.make("message-1"), |
| 678 | role: "assistant", | 678 | role: "assistant", |
| 679 | text: "hello", | 679 | text: "hello", |
| 680 | turnId: TurnId.makeUnsafe("turn-1"), | 680 | turnId: TurnId.make("turn-1"), |
| 681 | createdAt: "2026-02-27T00:00:00.000Z", | 681 | createdAt: "2026-02-27T00:00:00.000Z", |
| 682 | completedAt: "2026-02-27T00:00:00.000Z", | 682 | completedAt: "2026-02-27T00:00:00.000Z", |
| 683 | streaming: false, | 683 | streaming: false, |
| 684 | }, | 684 | }, |
| 685 | ], | 685 | ], |
| 686 | }); | 686 | }); |
| 687 | const thread2 = makeThread({ id: ThreadId.makeUnsafe("thread-2") }); | 687 | const thread2 = makeThread({ id: ThreadId.make("thread-2") }); |
| 688 | const baseState = makeState(thread1); | 688 | const baseState = makeState(thread1); |
| 689 | const baseEnvironmentState = localEnvironmentStateOf(baseState); | 689 | const baseEnvironmentState = localEnvironmentStateOf(baseState); |
| 690 | const state = withActiveEnvironmentState(baseEnvironmentState, { | 690 | const state = withActiveEnvironmentState(baseEnvironmentState, { |
| ... | @@ -762,10 +762,10 @@ describe("incremental orchestration updates", () => { | ... | @@ -762,10 +762,10 @@ describe("incremental orchestration updates", () => { |
| 762 | state, | 762 | state, |
| 763 | makeEvent("thread.message-sent", { | 763 | makeEvent("thread.message-sent", { |
| 764 | threadId: thread1.id, | 764 | threadId: thread1.id, |
| 765 | messageId: MessageId.makeUnsafe("message-1"), | 765 | messageId: MessageId.make("message-1"), |
| 766 | role: "assistant", | 766 | role: "assistant", |
| 767 | text: " world", | 767 | text: " world", |
| 768 | turnId: TurnId.makeUnsafe("turn-1"), | 768 | turnId: TurnId.make("turn-1"), |
| 769 | streaming: true, | 769 | streaming: true, |
| 770 | createdAt: "2026-02-27T00:00:01.000Z", | 770 | createdAt: "2026-02-27T00:00:01.000Z", |
| 771 | updatedAt: "2026-02-27T00:00:01.000Z", | 771 | updatedAt: "2026-02-27T00:00:01.000Z", |
| ... | @@ -794,7 +794,7 @@ describe("incremental orchestration updates", () => { | ... | @@ -794,7 +794,7 @@ describe("incremental orchestration updates", () => { |
| 794 | it("applies replay batches in sequence and updates session state", () => { | 794 | it("applies replay batches in sequence and updates session state", () => { |
| 795 | const thread = makeThread({ | 795 | const thread = makeThread({ |
| 796 | latestTurn: { | 796 | latestTurn: { |
| 797 | turnId: TurnId.makeUnsafe("turn-1"), | 797 | turnId: TurnId.make("turn-1"), |
| 798 | state: "running", | 798 | state: "running", |
| 799 | requestedAt: "2026-02-27T00:00:00.000Z", | 799 | requestedAt: "2026-02-27T00:00:00.000Z", |
| 800 | startedAt: "2026-02-27T00:00:00.000Z", | 800 | startedAt: "2026-02-27T00:00:00.000Z", |
| ... | @@ -816,7 +816,7 @@ describe("incremental orchestration updates", () => { | ... | @@ -816,7 +816,7 @@ describe("incremental orchestration updates", () => { |
| 816 | status: "running", | 816 | status: "running", |
| 817 | providerName: "codex", | 817 | providerName: "codex", |
| 818 | runtimeMode: "full-access", | 818 | runtimeMode: "full-access", |
| 819 | activeTurnId: TurnId.makeUnsafe("turn-1"), | 819 | activeTurnId: TurnId.make("turn-1"), |
| 820 | lastError: null, | 820 | lastError: null, |
| 821 | updatedAt: "2026-02-27T00:00:02.000Z", | 821 | updatedAt: "2026-02-27T00:00:02.000Z", |
| 822 | }, | 822 | }, |
| ... | @@ -827,10 +827,10 @@ describe("incremental orchestration updates", () => { | ... | @@ -827,10 +827,10 @@ describe("incremental orchestration updates", () => { |
| 827 | "thread.message-sent", | 827 | "thread.message-sent", |
| 828 | { | 828 | { |
| 829 | threadId: thread.id, | 829 | threadId: thread.id, |
| 830 | messageId: MessageId.makeUnsafe("assistant-1"), | 830 | messageId: MessageId.make("assistant-1"), |
| 831 | role: "assistant", | 831 | role: "assistant", |
| 832 | text: "done", | 832 | text: "done", |
| 833 | turnId: TurnId.makeUnsafe("turn-1"), | 833 | turnId: TurnId.make("turn-1"), |
| 834 | streaming: false, | 834 | streaming: false, |
| 835 | createdAt: "2026-02-27T00:00:03.000Z", | 835 | createdAt: "2026-02-27T00:00:03.000Z", |
| 836 | updatedAt: "2026-02-27T00:00:03.000Z", | 836 | updatedAt: "2026-02-27T00:00:03.000Z", |
| ... | @@ -850,7 +850,7 @@ describe("incremental orchestration updates", () => { | ... | @@ -850,7 +850,7 @@ describe("incremental orchestration updates", () => { |
| 850 | const state = makeState( | 850 | const state = makeState( |
| 851 | makeThread({ | 851 | makeThread({ |
| 852 | latestTurn: { | 852 | latestTurn: { |
| 853 | turnId: TurnId.makeUnsafe("turn-2"), | 853 | turnId: TurnId.make("turn-2"), |
| 854 | state: "running", | 854 | state: "running", |
| 855 | requestedAt: "2026-02-27T00:00:02.000Z", | 855 | requestedAt: "2026-02-27T00:00:02.000Z", |
| 856 | startedAt: "2026-02-27T00:00:03.000Z", | 856 | startedAt: "2026-02-27T00:00:03.000Z", |
| ... | @@ -863,13 +863,13 @@ describe("incremental orchestration updates", () => { | ... | @@ -863,13 +863,13 @@ describe("incremental orchestration updates", () => { |
| 863 | const next = applyOrchestrationEvent( | 863 | const next = applyOrchestrationEvent( |
| 864 | state, | 864 | state, |
| 865 | makeEvent("thread.turn-diff-completed", { | 865 | makeEvent("thread.turn-diff-completed", { |
| 866 | threadId: ThreadId.makeUnsafe("thread-1"), | 866 | threadId: ThreadId.make("thread-1"), |
| 867 | turnId: TurnId.makeUnsafe("turn-1"), | 867 | turnId: TurnId.make("turn-1"), |
| 868 | checkpointTurnCount: 1, | 868 | checkpointTurnCount: 1, |
| 869 | checkpointRef: CheckpointRef.makeUnsafe("checkpoint-1"), | 869 | checkpointRef: CheckpointRef.make("checkpoint-1"), |
| 870 | status: "ready", | 870 | status: "ready", |
| 871 | files: [], | 871 | files: [], |
| 872 | assistantMessageId: MessageId.makeUnsafe("assistant-1"), | 872 | assistantMessageId: MessageId.make("assistant-1"), |
| 873 | completedAt: "2026-02-27T00:00:04.000Z", | 873 | completedAt: "2026-02-27T00:00:04.000Z", |
| 874 | }), | 874 | }), |
| 875 | localEnvironmentId, | 875 | localEnvironmentId, |
| ... | @@ -880,7 +880,7 @@ describe("incremental orchestration updates", () => { | ... | @@ -880,7 +880,7 @@ describe("incremental orchestration updates", () => { |
| 880 | }); | 880 | }); |
| 881 | 881 | ||
| 882 | it("rebinds live turn diffs to the authoritative assistant message when it arrives later", () => { | 882 | it("rebinds live turn diffs to the authoritative assistant message when it arrives later", () => { |
| 883 | const turnId = TurnId.makeUnsafe("turn-1"); | 883 | const turnId = TurnId.make("turn-1"); |
| 884 | const state = makeState( | 884 | const state = makeState( |
| 885 | makeThread({ | 885 | makeThread({ |
| 886 | latestTurn: { | 886 | latestTurn: { |
| ... | @@ -889,7 +889,7 @@ describe("incremental orchestration updates", () => { | ... | @@ -889,7 +889,7 @@ describe("incremental orchestration updates", () => { |
| 889 | requestedAt: "2026-02-27T00:00:00.000Z", | 889 | requestedAt: "2026-02-27T00:00:00.000Z", |
| 890 | startedAt: "2026-02-27T00:00:00.000Z", | 890 | startedAt: "2026-02-27T00:00:00.000Z", |
| 891 | completedAt: "2026-02-27T00:00:02.000Z", | 891 | completedAt: "2026-02-27T00:00:02.000Z", |
| 892 | assistantMessageId: MessageId.makeUnsafe("assistant:turn-1"), | 892 | assistantMessageId: MessageId.make("assistant:turn-1"), |
| 893 | }, | 893 | }, |
| 894 | turnDiffSummaries: [ | 894 | turnDiffSummaries: [ |
| 895 | { | 895 | { |
| ... | @@ -897,8 +897,8 @@ describe("incremental orchestration updates", () => { | ... | @@ -897,8 +897,8 @@ describe("incremental orchestration updates", () => { |
| 897 | completedAt: "2026-02-27T00:00:02.000Z", | 897 | completedAt: "2026-02-27T00:00:02.000Z", |
| 898 | status: "ready", | 898 | status: "ready", |
| 899 | checkpointTurnCount: 1, | 899 | checkpointTurnCount: 1, |
| 900 | checkpointRef: CheckpointRef.makeUnsafe("checkpoint-1"), | 900 | checkpointRef: CheckpointRef.make("checkpoint-1"), |
| 901 | assistantMessageId: MessageId.makeUnsafe("assistant:turn-1"), | 901 | assistantMessageId: MessageId.make("assistant:turn-1"), |
| 902 | files: [{ path: "src/app.ts", additions: 1, deletions: 0 }], | 902 | files: [{ path: "src/app.ts", additions: 1, deletions: 0 }], |
| 903 | }, | 903 | }, |
| 904 | ], | 904 | ], |
| ... | @@ -908,8 +908,8 @@ describe("incremental orchestration updates", () => { | ... | @@ -908,8 +908,8 @@ describe("incremental orchestration updates", () => { |
| 908 | const next = applyOrchestrationEvent( | 908 | const next = applyOrchestrationEvent( |
| 909 | state, | 909 | state, |
| 910 | makeEvent("thread.message-sent", { | 910 | makeEvent("thread.message-sent", { |
| 911 | threadId: ThreadId.makeUnsafe("thread-1"), | 911 | threadId: ThreadId.make("thread-1"), |
| 912 | messageId: MessageId.makeUnsafe("assistant-real"), | 912 | messageId: MessageId.make("assistant-real"), |
| 913 | role: "assistant", | 913 | role: "assistant", |
| 914 | text: "final answer", | 914 | text: "final answer", |
| 915 | turnId, | 915 | turnId, |
| ... | @@ -921,10 +921,10 @@ describe("incremental orchestration updates", () => { | ... | @@ -921,10 +921,10 @@ describe("incremental orchestration updates", () => { |
| 921 | ); | 921 | ); |
| 922 | 922 | ||
| 923 | expect(threadsOf(next)[0]?.turnDiffSummaries[0]?.assistantMessageId).toBe( | 923 | expect(threadsOf(next)[0]?.turnDiffSummaries[0]?.assistantMessageId).toBe( |
| 924 | MessageId.makeUnsafe("assistant-real"), | 924 | MessageId.make("assistant-real"), |
| 925 | ); | 925 | ); |
| 926 | expect(threadsOf(next)[0]?.latestTurn?.assistantMessageId).toBe( | 926 | expect(threadsOf(next)[0]?.latestTurn?.assistantMessageId).toBe( |
| 927 | MessageId.makeUnsafe("assistant-real"), | 927 | MessageId.make("assistant-real"), |
| 928 | ); | 928 | ); |
| 929 | }); | 929 | }); |
| 930 | 930 | ||
| ... | @@ -933,28 +933,28 @@ describe("incremental orchestration updates", () => { | ... | @@ -933,28 +933,28 @@ describe("incremental orchestration updates", () => { |
| 933 | makeThread({ | 933 | makeThread({ |
| 934 | messages: [ | 934 | messages: [ |
| 935 | { | 935 | { |
| 936 | id: MessageId.makeUnsafe("user-1"), | 936 | id: MessageId.make("user-1"), |
| 937 | role: "user", | 937 | role: "user", |
| 938 | text: "first", | 938 | text: "first", |
| 939 | turnId: TurnId.makeUnsafe("turn-1"), | 939 | turnId: TurnId.make("turn-1"), |
| 940 | createdAt: "2026-02-27T00:00:00.000Z", | 940 | createdAt: "2026-02-27T00:00:00.000Z", |
| 941 | completedAt: "2026-02-27T00:00:00.000Z", | 941 | completedAt: "2026-02-27T00:00:00.000Z", |
| 942 | streaming: false, | 942 | streaming: false, |
| 943 | }, | 943 | }, |
| 944 | { | 944 | { |
| 945 | id: MessageId.makeUnsafe("assistant-1"), | 945 | id: MessageId.make("assistant-1"), |
| 946 | role: "assistant", | 946 | role: "assistant", |
| 947 | text: "first reply", | 947 | text: "first reply", |
| 948 | turnId: TurnId.makeUnsafe("turn-1"), | 948 | turnId: TurnId.make("turn-1"), |
| 949 | createdAt: "2026-02-27T00:00:01.000Z", | 949 | createdAt: "2026-02-27T00:00:01.000Z", |
| 950 | completedAt: "2026-02-27T00:00:01.000Z", | 950 | completedAt: "2026-02-27T00:00:01.000Z", |
| 951 | streaming: false, | 951 | streaming: false, |
| 952 | }, | 952 | }, |
| 953 | { | 953 | { |
| 954 | id: MessageId.makeUnsafe("user-2"), | 954 | id: MessageId.make("user-2"), |
| 955 | role: "user", | 955 | role: "user", |
| 956 | text: "second", | 956 | text: "second", |
| 957 | turnId: TurnId.makeUnsafe("turn-2"), | 957 | turnId: TurnId.make("turn-2"), |
| 958 | createdAt: "2026-02-27T00:00:02.000Z", | 958 | createdAt: "2026-02-27T00:00:02.000Z", |
| 959 | completedAt: "2026-02-27T00:00:02.000Z", | 959 | completedAt: "2026-02-27T00:00:02.000Z", |
| 960 | streaming: false, | 960 | streaming: false, |
| ... | @@ -963,7 +963,7 @@ describe("incremental orchestration updates", () => { | ... | @@ -963,7 +963,7 @@ describe("incremental orchestration updates", () => { |
| 963 | proposedPlans: [ | 963 | proposedPlans: [ |
| 964 | { | 964 | { |
| 965 | id: "plan-1", | 965 | id: "plan-1", |
| 966 | turnId: TurnId.makeUnsafe("turn-1"), | 966 | turnId: TurnId.make("turn-1"), |
| 967 | planMarkdown: "plan 1", | 967 | planMarkdown: "plan 1", |
| 968 | implementedAt: null, | 968 | implementedAt: null, |
| 969 | implementationThreadId: null, | 969 | implementationThreadId: null, |
| ... | @@ -972,7 +972,7 @@ describe("incremental orchestration updates", () => { | ... | @@ -972,7 +972,7 @@ describe("incremental orchestration updates", () => { |
| 972 | }, | 972 | }, |
| 973 | { | 973 | { |
| 974 | id: "plan-2", | 974 | id: "plan-2", |
| 975 | turnId: TurnId.makeUnsafe("turn-2"), | 975 | turnId: TurnId.make("turn-2"), |
| 976 | planMarkdown: "plan 2", | 976 | planMarkdown: "plan 2", |
| 977 | implementedAt: null, | 977 | implementedAt: null, |
| 978 | implementationThreadId: null, | 978 | implementationThreadId: null, |
| ... | @@ -982,39 +982,39 @@ describe("incremental orchestration updates", () => { | ... | @@ -982,39 +982,39 @@ describe("incremental orchestration updates", () => { |
| 982 | ], | 982 | ], |
| 983 | activities: [ | 983 | activities: [ |
| 984 | { | 984 | { |
| 985 | id: EventId.makeUnsafe("activity-1"), | 985 | id: EventId.make("activity-1"), |
| 986 | tone: "info", | 986 | tone: "info", |
| 987 | kind: "step", | 987 | kind: "step", |
| 988 | summary: "one", | 988 | summary: "one", |
| 989 | payload: {}, | 989 | payload: {}, |
| 990 | turnId: TurnId.makeUnsafe("turn-1"), | 990 | turnId: TurnId.make("turn-1"), |
| 991 | createdAt: "2026-02-27T00:00:00.000Z", | 991 | createdAt: "2026-02-27T00:00:00.000Z", |
| 992 | }, | 992 | }, |
| 993 | { | 993 | { |
| 994 | id: EventId.makeUnsafe("activity-2"), | 994 | id: EventId.make("activity-2"), |
| 995 | tone: "info", | 995 | tone: "info", |
| 996 | kind: "step", | 996 | kind: "step", |
| 997 | summary: "two", | 997 | summary: "two", |
| 998 | payload: {}, | 998 | payload: {}, |
| 999 | turnId: TurnId.makeUnsafe("turn-2"), | 999 | turnId: TurnId.make("turn-2"), |
| 1000 | createdAt: "2026-02-27T00:00:02.000Z", | 1000 | createdAt: "2026-02-27T00:00:02.000Z", |
| 1001 | }, | 1001 | }, |
| 1002 | ], | 1002 | ], |
| 1003 | turnDiffSummaries: [ | 1003 | turnDiffSummaries: [ |
| 1004 | { | 1004 | { |
| 1005 | turnId: TurnId.makeUnsafe("turn-1"), | 1005 | turnId: TurnId.make("turn-1"), |
| 1006 | completedAt: "2026-02-27T00:00:01.000Z", | 1006 | completedAt: "2026-02-27T00:00:01.000Z", |
| 1007 | status: "ready", | 1007 | status: "ready", |
| 1008 | checkpointTurnCount: 1, | 1008 | checkpointTurnCount: 1, |
| 1009 | checkpointRef: CheckpointRef.makeUnsafe("ref-1"), | 1009 | checkpointRef: CheckpointRef.make("ref-1"), |
| 1010 | files: [], | 1010 | files: [], |
| 1011 | }, | 1011 | }, |
| 1012 | { | 1012 | { |
| 1013 | turnId: TurnId.makeUnsafe("turn-2"), | 1013 | turnId: TurnId.make("turn-2"), |
| 1014 | completedAt: "2026-02-27T00:00:03.000Z", | 1014 | completedAt: "2026-02-27T00:00:03.000Z", |
| 1015 | status: "ready", | 1015 | status: "ready", |
| 1016 | checkpointTurnCount: 2, | 1016 | checkpointTurnCount: 2, |
| 1017 | checkpointRef: CheckpointRef.makeUnsafe("ref-2"), | 1017 | checkpointRef: CheckpointRef.make("ref-2"), |
| 1018 | files: [], | 1018 | files: [], |
| 1019 | }, | 1019 | }, |
| 1020 | ], | 1020 | ], |
| ... | @@ -1024,7 +1024,7 @@ describe("incremental orchestration updates", () => { | ... | @@ -1024,7 +1024,7 @@ describe("incremental orchestration updates", () => { |
| 1024 | const next = applyOrchestrationEvent( | 1024 | const next = applyOrchestrationEvent( |
| 1025 | state, | 1025 | state, |
| 1026 | makeEvent("thread.reverted", { | 1026 | makeEvent("thread.reverted", { |
| 1027 | threadId: ThreadId.makeUnsafe("thread-1"), | 1027 | threadId: ThreadId.make("thread-1"), |
| 1028 | turnCount: 1, | 1028 | turnCount: 1, |
| 1029 | }), | 1029 | }), |
| 1030 | localEnvironmentId, | 1030 | localEnvironmentId, |
| ... | @@ -1036,46 +1036,46 @@ describe("incremental orchestration updates", () => { | ... | @@ -1036,46 +1036,46 @@ describe("incremental orchestration updates", () => { |
| 1036 | ]); | 1036 | ]); |
| 1037 | expect(threadsOf(next)[0]?.proposedPlans.map((plan) => plan.id)).toEqual(["plan-1"]); | 1037 | expect(threadsOf(next)[0]?.proposedPlans.map((plan) => plan.id)).toEqual(["plan-1"]); |
| 1038 | expect(threadsOf(next)[0]?.activities.map((activity) => activity.id)).toEqual([ | 1038 | expect(threadsOf(next)[0]?.activities.map((activity) => activity.id)).toEqual([ |
| 1039 | EventId.makeUnsafe("activity-1"), | 1039 | EventId.make("activity-1"), |
| 1040 | ]); | 1040 | ]); |
| 1041 | expect(threadsOf(next)[0]?.turnDiffSummaries.map((summary) => summary.turnId)).toEqual([ | 1041 | expect(threadsOf(next)[0]?.turnDiffSummaries.map((summary) => summary.turnId)).toEqual([ |
| 1042 | TurnId.makeUnsafe("turn-1"), | 1042 | TurnId.make("turn-1"), |
| 1043 | ]); | 1043 | ]); |
| 1044 | }); | 1044 | }); |
| 1045 | 1045 | ||
| 1046 | it("clears pending source proposed plans after revert before a new session-set event", () => { | 1046 | it("clears pending source proposed plans after revert before a new session-set event", () => { |
| 1047 | const thread = makeThread({ | 1047 | const thread = makeThread({ |
| 1048 | latestTurn: { | 1048 | latestTurn: { |
| 1049 | turnId: TurnId.makeUnsafe("turn-2"), | 1049 | turnId: TurnId.make("turn-2"), |
| 1050 | state: "completed", | 1050 | state: "completed", |
| 1051 | requestedAt: "2026-02-27T00:00:02.000Z", | 1051 | requestedAt: "2026-02-27T00:00:02.000Z", |
| 1052 | startedAt: "2026-02-27T00:00:02.000Z", | 1052 | startedAt: "2026-02-27T00:00:02.000Z", |
| 1053 | completedAt: "2026-02-27T00:00:03.000Z", | 1053 | completedAt: "2026-02-27T00:00:03.000Z", |
| 1054 | assistantMessageId: MessageId.makeUnsafe("assistant-2"), | 1054 | assistantMessageId: MessageId.make("assistant-2"), |
| 1055 | sourceProposedPlan: { | 1055 | sourceProposedPlan: { |
| 1056 | threadId: ThreadId.makeUnsafe("thread-source"), | 1056 | threadId: ThreadId.make("thread-source"), |
| 1057 | planId: "plan-2" as never, | 1057 | planId: "plan-2" as never, |
| 1058 | }, | 1058 | }, |
| 1059 | }, | 1059 | }, |
| 1060 | pendingSourceProposedPlan: { | 1060 | pendingSourceProposedPlan: { |
| 1061 | threadId: ThreadId.makeUnsafe("thread-source"), | 1061 | threadId: ThreadId.make("thread-source"), |
| 1062 | planId: "plan-2" as never, | 1062 | planId: "plan-2" as never, |
| 1063 | }, | 1063 | }, |
| 1064 | turnDiffSummaries: [ | 1064 | turnDiffSummaries: [ |
| 1065 | { | 1065 | { |
| 1066 | turnId: TurnId.makeUnsafe("turn-1"), | 1066 | turnId: TurnId.make("turn-1"), |
| 1067 | completedAt: "2026-02-27T00:00:01.000Z", | 1067 | completedAt: "2026-02-27T00:00:01.000Z", |
| 1068 | status: "ready", | 1068 | status: "ready", |
| 1069 | checkpointTurnCount: 1, | 1069 | checkpointTurnCount: 1, |
| 1070 | checkpointRef: CheckpointRef.makeUnsafe("ref-1"), | 1070 | checkpointRef: CheckpointRef.make("ref-1"), |
| 1071 | files: [], | 1071 | files: [], |
| 1072 | }, | 1072 | }, |
| 1073 | { | 1073 | { |
| 1074 | turnId: TurnId.makeUnsafe("turn-2"), | 1074 | turnId: TurnId.make("turn-2"), |
| 1075 | completedAt: "2026-02-27T00:00:03.000Z", | 1075 | completedAt: "2026-02-27T00:00:03.000Z", |
| 1076 | status: "ready", | 1076 | status: "ready", |
| 1077 | checkpointTurnCount: 2, | 1077 | checkpointTurnCount: 2, |
| 1078 | checkpointRef: CheckpointRef.makeUnsafe("ref-2"), | 1078 | checkpointRef: CheckpointRef.make("ref-2"), |
| 1079 | files: [], | 1079 | files: [], |
| 1080 | }, | 1080 | }, |
| 1081 | ], | 1081 | ], |
| ... | @@ -1100,7 +1100,7 @@ describe("incremental orchestration updates", () => { | ... | @@ -1100,7 +1100,7 @@ describe("incremental orchestration updates", () => { |
| 1100 | status: "running", | 1100 | status: "running", |
| 1101 | providerName: "codex", | 1101 | providerName: "codex", |
| 1102 | runtimeMode: "full-access", | 1102 | runtimeMode: "full-access", |
| 1103 | activeTurnId: TurnId.makeUnsafe("turn-3"), | 1103 | activeTurnId: TurnId.make("turn-3"), |
| 1104 | lastError: null, | 1104 | lastError: null, |
| 1105 | updatedAt: "2026-02-27T00:00:04.000Z", | 1105 | updatedAt: "2026-02-27T00:00:04.000Z", |
| 1106 | }, | 1106 | }, |
| ... | @@ -1109,7 +1109,7 @@ describe("incremental orchestration updates", () => { | ... | @@ -1109,7 +1109,7 @@ describe("incremental orchestration updates", () => { |
| 1109 | ); | 1109 | ); |
| 1110 | 1110 | ||
| 1111 | expect(threadsOf(next)[0]?.latestTurn).toMatchObject({ | 1111 | expect(threadsOf(next)[0]?.latestTurn).toMatchObject({ |
| 1112 | turnId: TurnId.makeUnsafe("turn-3"), | 1112 | turnId: TurnId.make("turn-3"), |
| 1113 | state: "running", | 1113 | state: "running", |
| 1114 | }); | 1114 | }); |
| 1115 | expect(threadsOf(next)[0]?.latestTurn?.sourceProposedPlan).toBeUndefined(); | 1115 | expect(threadsOf(next)[0]?.latestTurn?.sourceProposedPlan).toBeUndefined(); |
apps/web/src/terminalStateStore.test.ts+1-1| ... | @@ -9,7 +9,7 @@ import { | ... | @@ -9,7 +9,7 @@ import { |
| 9 | useTerminalStateStore, | 9 | useTerminalStateStore, |
| 10 | } from "./terminalStateStore"; | 10 | } from "./terminalStateStore"; |
| 11 | 11 | ||
| 12 | const THREAD_ID = ThreadId.makeUnsafe("thread-1"); | 12 | const THREAD_ID = ThreadId.make("thread-1"); |
| 13 | const THREAD_REF = scopeThreadRef("environment-a" as never, THREAD_ID); | 13 | const THREAD_REF = scopeThreadRef("environment-a" as never, THREAD_ID); |
| 14 | const OTHER_THREAD_REF = scopeThreadRef("environment-b" as never, THREAD_ID); | 14 | const OTHER_THREAD_REF = scopeThreadRef("environment-b" as never, THREAD_ID); |
| 15 | 15 |
apps/web/src/threadRoutes.test.ts+2-2| ... | @@ -12,7 +12,7 @@ import { | ... | @@ -12,7 +12,7 @@ import { |
| 12 | 12 | ||
| 13 | describe("threadRoutes", () => { | 13 | describe("threadRoutes", () => { |
| 14 | it("builds canonical thread route params from a scoped ref", () => { | 14 | it("builds canonical thread route params from a scoped ref", () => { |
| 15 | const ref = scopeThreadRef("env-1" as never, ThreadId.makeUnsafe("thread-1")); | 15 | const ref = scopeThreadRef("env-1" as never, ThreadId.make("thread-1")); |
| 16 | 16 | ||
| 17 | expect(buildThreadRouteParams(ref)).toEqual({ | 17 | expect(buildThreadRouteParams(ref)).toEqual({ |
| 18 | environmentId: "env-1", | 18 | environmentId: "env-1", |
| ... | @@ -36,7 +36,7 @@ describe("threadRoutes", () => { | ... | @@ -36,7 +36,7 @@ describe("threadRoutes", () => { |
| 36 | }); | 36 | }); |
| 37 | 37 | ||
| 38 | it("builds canonical draft route params from a draft id", () => { | 38 | it("builds canonical draft route params from a draft id", () => { |
| 39 | expect(buildDraftThreadRouteParams(DraftId.makeUnsafe("draft-1"))).toEqual({ | 39 | expect(buildDraftThreadRouteParams(DraftId.make("draft-1"))).toEqual({ |
| 40 | draftId: "draft-1", | 40 | draftId: "draft-1", |
| 41 | }); | 41 | }); |
| 42 | }); | 42 | }); |
apps/web/src/threadSelectionStore.test.ts+6-6| ... | @@ -3,11 +3,11 @@ import { beforeEach, describe, expect, it } from "vitest"; | ... | @@ -3,11 +3,11 @@ import { beforeEach, describe, expect, it } from "vitest"; |
| 3 | 3 | ||
| 4 | import { useThreadSelectionStore } from "./threadSelectionStore"; | 4 | import { useThreadSelectionStore } from "./threadSelectionStore"; |
| 5 | 5 | ||
| 6 | const THREAD_A = ThreadId.makeUnsafe("thread-a"); | 6 | const THREAD_A = ThreadId.make("thread-a"); |
| 7 | const THREAD_B = ThreadId.makeUnsafe("thread-b"); | 7 | const THREAD_B = ThreadId.make("thread-b"); |
| 8 | const THREAD_C = ThreadId.makeUnsafe("thread-c"); | 8 | const THREAD_C = ThreadId.make("thread-c"); |
| 9 | const THREAD_D = ThreadId.makeUnsafe("thread-d"); | 9 | const THREAD_D = ThreadId.make("thread-d"); |
| 10 | const THREAD_E = ThreadId.makeUnsafe("thread-e"); | 10 | const THREAD_E = ThreadId.make("thread-e"); |
| 11 | 11 | ||
| 12 | const ORDERED = [THREAD_A, THREAD_B, THREAD_C, THREAD_D, THREAD_E] as const; | 12 | const ORDERED = [THREAD_A, THREAD_B, THREAD_C, THREAD_D, THREAD_E] as const; |
| 13 | 13 | ||
| ... | @@ -173,7 +173,7 @@ describe("threadSelectionStore", () => { | ... | @@ -173,7 +173,7 @@ describe("threadSelectionStore", () => { |
| 173 | it("falls back to toggle when target is not in the ordered list", () => { | 173 | it("falls back to toggle when target is not in the ordered list", () => { |
| 174 | const store = useThreadSelectionStore.getState(); | 174 | const store = useThreadSelectionStore.getState(); |
| 175 | store.toggleThread(THREAD_B); // anchor = B | 175 | store.toggleThread(THREAD_B); // anchor = B |
| 176 | const unknownThread = ThreadId.makeUnsafe("thread-unknown"); | 176 | const unknownThread = ThreadId.make("thread-unknown"); |
| 177 | store.rangeSelectTo(unknownThread, ORDERED); | 177 | store.rangeSelectTo(unknownThread, ORDERED); |
| 178 | 178 | ||
| 179 | const state = useThreadSelectionStore.getState(); | 179 | const state = useThreadSelectionStore.getState(); |
apps/web/src/uiStateStore.test.ts+17-17| ... | @@ -22,7 +22,7 @@ function makeUiState(overrides: Partial<UiState> = {}): UiState { | ... | @@ -22,7 +22,7 @@ function makeUiState(overrides: Partial<UiState> = {}): UiState { |
| 22 | 22 | ||
| 23 | describe("uiStateStore pure functions", () => { | 23 | describe("uiStateStore pure functions", () => { |
| 24 | it("markThreadUnread moves lastVisitedAt before completion for a completed thread", () => { | 24 | it("markThreadUnread moves lastVisitedAt before completion for a completed thread", () => { |
| 25 | const threadId = ThreadId.makeUnsafe("thread-1"); | 25 | const threadId = ThreadId.make("thread-1"); |
| 26 | const latestTurnCompletedAt = "2026-02-25T12:30:00.000Z"; | 26 | const latestTurnCompletedAt = "2026-02-25T12:30:00.000Z"; |
| 27 | const initialState = makeUiState({ | 27 | const initialState = makeUiState({ |
| 28 | threadLastVisitedAtById: { | 28 | threadLastVisitedAtById: { |
| ... | @@ -36,7 +36,7 @@ describe("uiStateStore pure functions", () => { | ... | @@ -36,7 +36,7 @@ describe("uiStateStore pure functions", () => { |
| 36 | }); | 36 | }); |
| 37 | 37 | ||
| 38 | it("markThreadUnread does not change a thread without a completed turn", () => { | 38 | it("markThreadUnread does not change a thread without a completed turn", () => { |
| 39 | const threadId = ThreadId.makeUnsafe("thread-1"); | 39 | const threadId = ThreadId.make("thread-1"); |
| 40 | const initialState = makeUiState({ | 40 | const initialState = makeUiState({ |
| 41 | threadLastVisitedAtById: { | 41 | threadLastVisitedAtById: { |
| 42 | [threadId]: "2026-02-25T12:35:00.000Z", | 42 | [threadId]: "2026-02-25T12:35:00.000Z", |
| ... | @@ -49,9 +49,9 @@ describe("uiStateStore pure functions", () => { | ... | @@ -49,9 +49,9 @@ describe("uiStateStore pure functions", () => { |
| 49 | }); | 49 | }); |
| 50 | 50 | ||
| 51 | it("reorderProjects moves a project to a target index", () => { | 51 | it("reorderProjects moves a project to a target index", () => { |
| 52 | const project1 = ProjectId.makeUnsafe("project-1"); | 52 | const project1 = ProjectId.make("project-1"); |
| 53 | const project2 = ProjectId.makeUnsafe("project-2"); | 53 | const project2 = ProjectId.make("project-2"); |
| 54 | const project3 = ProjectId.makeUnsafe("project-3"); | 54 | const project3 = ProjectId.make("project-3"); |
| 55 | const initialState = makeUiState({ | 55 | const initialState = makeUiState({ |
| 56 | projectOrder: [project1, project2, project3], | 56 | projectOrder: [project1, project2, project3], |
| 57 | }); | 57 | }); |
| ... | @@ -62,9 +62,9 @@ describe("uiStateStore pure functions", () => { | ... | @@ -62,9 +62,9 @@ describe("uiStateStore pure functions", () => { |
| 62 | }); | 62 | }); |
| 63 | 63 | ||
| 64 | it("syncProjects preserves current project order during snapshot recovery", () => { | 64 | it("syncProjects preserves current project order during snapshot recovery", () => { |
| 65 | const project1 = ProjectId.makeUnsafe("project-1"); | 65 | const project1 = ProjectId.make("project-1"); |
| 66 | const project2 = ProjectId.makeUnsafe("project-2"); | 66 | const project2 = ProjectId.make("project-2"); |
| 67 | const project3 = ProjectId.makeUnsafe("project-3"); | 67 | const project3 = ProjectId.make("project-3"); |
| 68 | const initialState = makeUiState({ | 68 | const initialState = makeUiState({ |
| 69 | projectExpandedById: { | 69 | projectExpandedById: { |
| 70 | [project1]: true, | 70 | [project1]: true, |
| ... | @@ -84,9 +84,9 @@ describe("uiStateStore pure functions", () => { | ... | @@ -84,9 +84,9 @@ describe("uiStateStore pure functions", () => { |
| 84 | }); | 84 | }); |
| 85 | 85 | ||
| 86 | it("syncProjects preserves manual order when a project is recreated with the same cwd", () => { | 86 | it("syncProjects preserves manual order when a project is recreated with the same cwd", () => { |
| 87 | const oldProject1 = ProjectId.makeUnsafe("project-1"); | 87 | const oldProject1 = ProjectId.make("project-1"); |
| 88 | const oldProject2 = ProjectId.makeUnsafe("project-2"); | 88 | const oldProject2 = ProjectId.make("project-2"); |
| 89 | const recreatedProject2 = ProjectId.makeUnsafe("project-2b"); | 89 | const recreatedProject2 = ProjectId.make("project-2b"); |
| 90 | const initialState = syncProjects( | 90 | const initialState = syncProjects( |
| 91 | makeUiState({ | 91 | makeUiState({ |
| 92 | projectExpandedById: { | 92 | projectExpandedById: { |
| ... | @@ -111,7 +111,7 @@ describe("uiStateStore pure functions", () => { | ... | @@ -111,7 +111,7 @@ describe("uiStateStore pure functions", () => { |
| 111 | }); | 111 | }); |
| 112 | 112 | ||
| 113 | it("syncProjects returns a new state when only project cwd changes", () => { | 113 | it("syncProjects returns a new state when only project cwd changes", () => { |
| 114 | const project1 = ProjectId.makeUnsafe("project-1"); | 114 | const project1 = ProjectId.make("project-1"); |
| 115 | const initialState = syncProjects( | 115 | const initialState = syncProjects( |
| 116 | makeUiState({ | 116 | makeUiState({ |
| 117 | projectExpandedById: { | 117 | projectExpandedById: { |
| ... | @@ -130,8 +130,8 @@ describe("uiStateStore pure functions", () => { | ... | @@ -130,8 +130,8 @@ describe("uiStateStore pure functions", () => { |
| 130 | }); | 130 | }); |
| 131 | 131 | ||
| 132 | it("syncThreads prunes missing thread UI state", () => { | 132 | it("syncThreads prunes missing thread UI state", () => { |
| 133 | const thread1 = ThreadId.makeUnsafe("thread-1"); | 133 | const thread1 = ThreadId.make("thread-1"); |
| 134 | const thread2 = ThreadId.makeUnsafe("thread-2"); | 134 | const thread2 = ThreadId.make("thread-2"); |
| 135 | const initialState = makeUiState({ | 135 | const initialState = makeUiState({ |
| 136 | threadLastVisitedAtById: { | 136 | threadLastVisitedAtById: { |
| 137 | [thread1]: "2026-02-25T12:35:00.000Z", | 137 | [thread1]: "2026-02-25T12:35:00.000Z", |
| ... | @@ -147,7 +147,7 @@ describe("uiStateStore pure functions", () => { | ... | @@ -147,7 +147,7 @@ describe("uiStateStore pure functions", () => { |
| 147 | }); | 147 | }); |
| 148 | 148 | ||
| 149 | it("syncThreads seeds visit state for unseen snapshot threads", () => { | 149 | it("syncThreads seeds visit state for unseen snapshot threads", () => { |
| 150 | const thread1 = ThreadId.makeUnsafe("thread-1"); | 150 | const thread1 = ThreadId.make("thread-1"); |
| 151 | const initialState = makeUiState(); | 151 | const initialState = makeUiState(); |
| 152 | 152 | ||
| 153 | const next = syncThreads(initialState, [ | 153 | const next = syncThreads(initialState, [ |
| ... | @@ -163,7 +163,7 @@ describe("uiStateStore pure functions", () => { | ... | @@ -163,7 +163,7 @@ describe("uiStateStore pure functions", () => { |
| 163 | }); | 163 | }); |
| 164 | 164 | ||
| 165 | it("setProjectExpanded updates expansion without touching order", () => { | 165 | it("setProjectExpanded updates expansion without touching order", () => { |
| 166 | const project1 = ProjectId.makeUnsafe("project-1"); | 166 | const project1 = ProjectId.make("project-1"); |
| 167 | const initialState = makeUiState({ | 167 | const initialState = makeUiState({ |
| 168 | projectExpandedById: { | 168 | projectExpandedById: { |
| 169 | [project1]: true, | 169 | [project1]: true, |
| ... | @@ -178,7 +178,7 @@ describe("uiStateStore pure functions", () => { | ... | @@ -178,7 +178,7 @@ describe("uiStateStore pure functions", () => { |
| 178 | }); | 178 | }); |
| 179 | 179 | ||
| 180 | it("clearThreadUi removes visit state for deleted threads", () => { | 180 | it("clearThreadUi removes visit state for deleted threads", () => { |
| 181 | const thread1 = ThreadId.makeUnsafe("thread-1"); | 181 | const thread1 = ThreadId.make("thread-1"); |
| 182 | const initialState = makeUiState({ | 182 | const initialState = makeUiState({ |
| 183 | threadLastVisitedAtById: { | 183 | threadLastVisitedAtById: { |
| 184 | [thread1]: "2026-02-25T12:35:00.000Z", | 184 | [thread1]: "2026-02-25T12:35:00.000Z", |
apps/web/src/worktreeCleanup.test.ts+12-12| ... | @@ -4,14 +4,14 @@ import { describe, expect, it } from "vitest"; | ... | @@ -4,14 +4,14 @@ import { describe, expect, it } from "vitest"; |
| 4 | import { DEFAULT_INTERACTION_MODE, DEFAULT_RUNTIME_MODE, type Thread } from "./types"; | 4 | import { DEFAULT_INTERACTION_MODE, DEFAULT_RUNTIME_MODE, type Thread } from "./types"; |
| 5 | import { formatWorktreePathForDisplay, getOrphanedWorktreePathForThread } from "./worktreeCleanup"; | 5 | import { formatWorktreePathForDisplay, getOrphanedWorktreePathForThread } from "./worktreeCleanup"; |
| 6 | 6 | ||
| 7 | const localEnvironmentId = EnvironmentId.makeUnsafe("environment-local"); | 7 | const localEnvironmentId = EnvironmentId.make("environment-local"); |
| 8 | 8 | ||
| 9 | function makeThread(overrides: Partial<Thread> = {}): Thread { | 9 | function makeThread(overrides: Partial<Thread> = {}): Thread { |
| 10 | return { | 10 | return { |
| 11 | id: ThreadId.makeUnsafe("thread-1"), | 11 | id: ThreadId.make("thread-1"), |
| 12 | environmentId: localEnvironmentId, | 12 | environmentId: localEnvironmentId, |
| 13 | codexThreadId: null, | 13 | codexThreadId: null, |
| 14 | projectId: ProjectId.makeUnsafe("project-1"), | 14 | projectId: ProjectId.make("project-1"), |
| 15 | title: "Thread", | 15 | title: "Thread", |
| 16 | modelSelection: { | 16 | modelSelection: { |
| 17 | provider: "codex", | 17 | provider: "codex", |
| ... | @@ -36,49 +36,49 @@ function makeThread(overrides: Partial<Thread> = {}): Thread { | ... | @@ -36,49 +36,49 @@ function makeThread(overrides: Partial<Thread> = {}): Thread { |
| 36 | 36 | ||
| 37 | describe("getOrphanedWorktreePathForThread", () => { | 37 | describe("getOrphanedWorktreePathForThread", () => { |
| 38 | it("returns null when the target thread does not exist", () => { | 38 | it("returns null when the target thread does not exist", () => { |
| 39 | const result = getOrphanedWorktreePathForThread([], ThreadId.makeUnsafe("missing-thread")); | 39 | const result = getOrphanedWorktreePathForThread([], ThreadId.make("missing-thread")); |
| 40 | expect(result).toBeNull(); | 40 | expect(result).toBeNull(); |
| 41 | }); | 41 | }); |
| 42 | 42 | ||
| 43 | it("returns null when the target thread has no worktree", () => { | 43 | it("returns null when the target thread has no worktree", () => { |
| 44 | const threads = [makeThread()]; | 44 | const threads = [makeThread()]; |
| 45 | const result = getOrphanedWorktreePathForThread(threads, ThreadId.makeUnsafe("thread-1")); | 45 | const result = getOrphanedWorktreePathForThread(threads, ThreadId.make("thread-1")); |
| 46 | expect(result).toBeNull(); | 46 | expect(result).toBeNull(); |
| 47 | }); | 47 | }); |
| 48 | 48 | ||
| 49 | it("returns the path when no other thread links to that worktree", () => { | 49 | it("returns the path when no other thread links to that worktree", () => { |
| 50 | const threads = [makeThread({ worktreePath: "/tmp/repo/worktrees/feature-a" })]; | 50 | const threads = [makeThread({ worktreePath: "/tmp/repo/worktrees/feature-a" })]; |
| 51 | const result = getOrphanedWorktreePathForThread(threads, ThreadId.makeUnsafe("thread-1")); | 51 | const result = getOrphanedWorktreePathForThread(threads, ThreadId.make("thread-1")); |
| 52 | expect(result).toBe("/tmp/repo/worktrees/feature-a"); | 52 | expect(result).toBe("/tmp/repo/worktrees/feature-a"); |
| 53 | }); | 53 | }); |
| 54 | 54 | ||
| 55 | it("returns null when another thread links to the same worktree", () => { | 55 | it("returns null when another thread links to the same worktree", () => { |
| 56 | const threads = [ | 56 | const threads = [ |
| 57 | makeThread({ | 57 | makeThread({ |
| 58 | id: ThreadId.makeUnsafe("thread-1"), | 58 | id: ThreadId.make("thread-1"), |
| 59 | worktreePath: "/tmp/repo/worktrees/feature-a", | 59 | worktreePath: "/tmp/repo/worktrees/feature-a", |
| 60 | }), | 60 | }), |
| 61 | makeThread({ | 61 | makeThread({ |
| 62 | id: ThreadId.makeUnsafe("thread-2"), | 62 | id: ThreadId.make("thread-2"), |
| 63 | worktreePath: "/tmp/repo/worktrees/feature-a", | 63 | worktreePath: "/tmp/repo/worktrees/feature-a", |
| 64 | }), | 64 | }), |
| 65 | ]; | 65 | ]; |
| 66 | const result = getOrphanedWorktreePathForThread(threads, ThreadId.makeUnsafe("thread-1")); | 66 | const result = getOrphanedWorktreePathForThread(threads, ThreadId.make("thread-1")); |
| 67 | expect(result).toBeNull(); | 67 | expect(result).toBeNull(); |
| 68 | }); | 68 | }); |
| 69 | 69 | ||
| 70 | it("ignores threads linked to different worktrees", () => { | 70 | it("ignores threads linked to different worktrees", () => { |
| 71 | const threads = [ | 71 | const threads = [ |
| 72 | makeThread({ | 72 | makeThread({ |
| 73 | id: ThreadId.makeUnsafe("thread-1"), | 73 | id: ThreadId.make("thread-1"), |
| 74 | worktreePath: "/tmp/repo/worktrees/feature-a", | 74 | worktreePath: "/tmp/repo/worktrees/feature-a", |
| 75 | }), | 75 | }), |
| 76 | makeThread({ | 76 | makeThread({ |
| 77 | id: ThreadId.makeUnsafe("thread-2"), | 77 | id: ThreadId.make("thread-2"), |
| 78 | worktreePath: "/tmp/repo/worktrees/feature-b", | 78 | worktreePath: "/tmp/repo/worktrees/feature-b", |
| 79 | }), | 79 | }), |
| 80 | ]; | 80 | ]; |
| 81 | const result = getOrphanedWorktreePathForThread(threads, ThreadId.makeUnsafe("thread-1")); | 81 | const result = getOrphanedWorktreePathForThread(threads, ThreadId.make("thread-1")); |
| 82 | expect(result).toBe("/tmp/repo/worktrees/feature-a"); | 82 | expect(result).toBe("/tmp/repo/worktrees/feature-a"); |
| 83 | }); | 83 | }); |
| 84 | }); | 84 | }); |
apps/web/test/authHttpHandlers.ts+1-1| ... | @@ -7,7 +7,7 @@ import { HttpResponse, http } from "msw"; | ... | @@ -7,7 +7,7 @@ import { HttpResponse, http } from "msw"; |
| 7 | 7 | ||
| 8 | const TEST_SESSION_EXPIRES_AT = "2026-05-01T12:00:00.000Z"; | 8 | const TEST_SESSION_EXPIRES_AT = "2026-05-01T12:00:00.000Z"; |
| 9 | const TEST_ENVIRONMENT_DESCRIPTOR: ExecutionEnvironmentDescriptor = { | 9 | const TEST_ENVIRONMENT_DESCRIPTOR: ExecutionEnvironmentDescriptor = { |
| 10 | environmentId: EnvironmentId.makeUnsafe("environment-local"), | 10 | environmentId: EnvironmentId.make("environment-local"), |
| 11 | label: "Local environment", | 11 | label: "Local environment", |
| 12 | platform: { | 12 | platform: { |
| 13 | os: "darwin", | 13 | os: "darwin", |
bun.lock+14-14| ... | @@ -189,16 +189,16 @@ | ... | @@ -189,16 +189,16 @@ |
| 189 | "vite": "^8.0.0", | 189 | "vite": "^8.0.0", |
| 190 | }, | 190 | }, |
| 191 | "catalog": { | 191 | "catalog": { |
| 192 | "@effect/atom-react": "4.0.0-beta.43", | 192 | "@effect/atom-react": "4.0.0-beta.45", |
| 193 | "@effect/language-service": "0.84.2", | 193 | "@effect/language-service": "0.84.2", |
| 194 | "@effect/platform-bun": "4.0.0-beta.43", | 194 | "@effect/platform-bun": "4.0.0-beta.45", |
| 195 | "@effect/platform-node": "4.0.0-beta.43", | 195 | "@effect/platform-node": "4.0.0-beta.45", |
| 196 | "@effect/platform-node-shared": "4.0.0-beta.43", | 196 | "@effect/platform-node-shared": "4.0.0-beta.45", |
| 197 | "@effect/sql-sqlite-bun": "4.0.0-beta.43", | 197 | "@effect/sql-sqlite-bun": "4.0.0-beta.45", |
| 198 | "@effect/vitest": "4.0.0-beta.43", | 198 | "@effect/vitest": "4.0.0-beta.45", |
| 199 | "@types/bun": "^1.3.9", | 199 | "@types/bun": "^1.3.9", |
| 200 | "@types/node": "^24.10.13", | 200 | "@types/node": "^24.10.13", |
| 201 | "effect": "4.0.0-beta.43", | 201 | "effect": "4.0.0-beta.45", |
| 202 | "tsdown": "^0.20.3", | 202 | "tsdown": "^0.20.3", |
| 203 | "typescript": "^5.7.3", | 203 | "typescript": "^5.7.3", |
| 204 | "vitest": "^4.0.0", | 204 | "vitest": "^4.0.0", |
| ... | @@ -284,19 +284,19 @@ | ... | @@ -284,19 +284,19 @@ |
| 284 | 284 | ||
| 285 | "@dnd-kit/utilities": ["@dnd-kit/utilities@3.2.2", "", { "dependencies": { "tslib": "^2.0.0" }, "peerDependencies": { "react": ">=16.8.0" } }, "sha512-+MKAJEOfaBe5SmV6t34p80MMKhjvUz0vRrvVJbPT0WElzaOJ/1xs+D+KDv+tD/NE5ujfrChEcshd4fLn0wpiqg=="], | 285 | "@dnd-kit/utilities": ["@dnd-kit/utilities@3.2.2", "", { "dependencies": { "tslib": "^2.0.0" }, "peerDependencies": { "react": ">=16.8.0" } }, "sha512-+MKAJEOfaBe5SmV6t34p80MMKhjvUz0vRrvVJbPT0WElzaOJ/1xs+D+KDv+tD/NE5ujfrChEcshd4fLn0wpiqg=="], |
| 286 | 286 | ||
| 287 | "@effect/atom-react": ["@effect/atom-react@4.0.0-beta.43", "", { "peerDependencies": { "effect": "^4.0.0-beta.43", "react": "^19.2.4", "scheduler": "*" } }, "sha512-xSrRbGXuo4d0g4ph66TQST1GNSjtQZrZj8V7OiAQFuzMYcZ0kwRIPUUFwOBtbWHK43/zNENdNWOnlXh/iYM1dw=="], | 287 | "@effect/atom-react": ["@effect/atom-react@4.0.0-beta.45", "", { "peerDependencies": { "effect": "^4.0.0-beta.45", "react": "^19.2.4", "scheduler": "*" } }, "sha512-jCoiae9UNeis9Yoal1p5V/P4eJK9nX89wORom7X5LpR2Ok920SZJc8dIeYkRXRAp9BCYJ/yWcO8gGLf7do71vg=="], |
| 288 | 288 | ||
| 289 | "@effect/language-service": ["@effect/language-service@0.84.2", "", { "bin": { "effect-language-service": "cli.js" } }, "sha512-l04qNxpiA8rY5yXWckRPJ7Mk5MNerXuNymSFf+IdflfI5i8jgL1bpBNLuP6ijg7wgjdHc/KmTnCj2kT0SCntuA=="], | 289 | "@effect/language-service": ["@effect/language-service@0.84.2", "", { "bin": { "effect-language-service": "cli.js" } }, "sha512-l04qNxpiA8rY5yXWckRPJ7Mk5MNerXuNymSFf+IdflfI5i8jgL1bpBNLuP6ijg7wgjdHc/KmTnCj2kT0SCntuA=="], |
| 290 | 290 | ||
| 291 | "@effect/platform-bun": ["@effect/platform-bun@4.0.0-beta.43", "", { "dependencies": { "@effect/platform-node-shared": "^4.0.0-beta.43" }, "peerDependencies": { "effect": "^4.0.0-beta.43" } }, "sha512-nMZ9JsD6CzJNQ+5pDUFbPw7PSZdQdTQ092MbYrocVtvlf6qEFU/hji3ITvRIOX7eabyQ8AUyp55qFPQUeq+GIA=="], | 291 | "@effect/platform-bun": ["@effect/platform-bun@4.0.0-beta.45", "", { "dependencies": { "@effect/platform-node-shared": "^4.0.0-beta.45" }, "peerDependencies": { "effect": "^4.0.0-beta.45" } }, "sha512-dZsbkJ+o4JfKE1OIAlMq8YWhmEfXxtTYennYADK/M/XlOtkFLsc2jkZppDvMznVni6JpFxWc7wd5rUf8jBVP5g=="], |
| 292 | 292 | ||
| 293 | "@effect/platform-node": ["@effect/platform-node@4.0.0-beta.43", "", { "dependencies": { "@effect/platform-node-shared": "^4.0.0-beta.43", "mime": "^4.1.0", "undici": "^7.24.0" }, "peerDependencies": { "effect": "^4.0.0-beta.43", "ioredis": "^5.7.0" } }, "sha512-Uq6E1rjaIpjHauzjwoB2HzAg3battYt2Boy8XO50GoHiWCXKE6WapYZ0/AnaBx5v5qg2sOfqpuiLsUf9ZgxOkA=="], | 293 | "@effect/platform-node": ["@effect/platform-node@4.0.0-beta.45", "", { "dependencies": { "@effect/platform-node-shared": "^4.0.0-beta.45", "mime": "^4.1.0", "undici": "^7.24.0" }, "peerDependencies": { "effect": "^4.0.0-beta.45", "ioredis": "^5.7.0" } }, "sha512-P07NMG4eoy62iLX9szak0hkr7hrwgq5+XMkm7URVug/3zqfZVxEG2kxn9JzVK1lF5WbaVrEKwjt3IkEJxzSPtg=="], |
| 294 | 294 | ||
| 295 | "@effect/platform-node-shared": ["@effect/platform-node-shared@4.0.0-beta.43", "", { "dependencies": { "@types/ws": "^8.18.1", "ws": "^8.19.0" }, "peerDependencies": { "effect": "^4.0.0-beta.43" } }, "sha512-A9q0GEb61pYcQ06Dr6gXj1nKlDI3KHsar1sk3qb1ZY+kVSR64tBAylI8zGon23KY+NPtTUj/sEIToB7jc3Qt5w=="], | 295 | "@effect/platform-node-shared": ["@effect/platform-node-shared@4.0.0-beta.45", "", { "dependencies": { "@types/ws": "^8.18.1", "ws": "^8.19.0" }, "peerDependencies": { "effect": "^4.0.0-beta.45" } }, "sha512-0T4RG18o+aCVUSlmPxA7uAjHJkyE3MS/uRrR5kCNSZQNG3X71wdIbu82wE/MnV6+6YSSPDx/6TVdZWYkJF0JWw=="], |
| 296 | 296 | ||
| 297 | "@effect/sql-sqlite-bun": ["@effect/sql-sqlite-bun@4.0.0-beta.43", "", { "peerDependencies": { "effect": "^4.0.0-beta.43" } }, "sha512-Ryb7x0rBjW5NHegbzvz9y2Yv4KpwZ1UiPk7/Rv+Mkux74Qkjdmotmrvy9P+M5A9TZyL2Av+GpaLTPJKsL0PG+Q=="], | 297 | "@effect/sql-sqlite-bun": ["@effect/sql-sqlite-bun@4.0.0-beta.45", "", { "peerDependencies": { "effect": "^4.0.0-beta.45" } }, "sha512-sJBBztwI4YxjdjhdyjWelh3KKoZucmmZS2ONeNDIzYgqFlsrwEEUrhVkWf5ch9Io+kUUzeb6q7/SedFoLUWO7g=="], |
| 298 | 298 | ||
| 299 | "@effect/vitest": ["@effect/vitest@4.0.0-beta.43", "", { "peerDependencies": { "effect": "^4.0.0-beta.43", "vitest": "^3.0.0 || ^4.0.0" } }, "sha512-XN2LAwiUWPqbV2jrsYYRjrVydQ8MIgwr83MVImtUaOQco4vk43+8OHlXQMRN/u2HnGK29KT+O2yTMMBdk2Q6Sw=="], | 299 | "@effect/vitest": ["@effect/vitest@4.0.0-beta.45", "", { "peerDependencies": { "effect": "^4.0.0-beta.45", "vitest": "^3.0.0 || ^4.0.0" } }, "sha512-38JA5Z6c2FoEhpVKbl7rjTrMU8Al5T30Kwtb6N3B9kOkyr2SsmvNsP9T65bh03IBh3ak9U//acrkmjS3hLQwKA=="], |
| 300 | 300 | ||
| 301 | "@electron/get": ["@electron/get@2.0.3", "", { "dependencies": { "debug": "^4.1.1", "env-paths": "^2.2.0", "fs-extra": "^8.1.0", "got": "^11.8.5", "progress": "^2.0.3", "semver": "^6.2.0", "sumchecker": "^3.0.1" }, "optionalDependencies": { "global-agent": "^3.0.0" } }, "sha512-Qkzpg2s9GnVV2I2BjRksUi43U5e6+zaQMcjoJy0C+C5oxaKl+fmckGDQFtRpZpZV0NQekuZZ+tGz7EA9TVnQtQ=="], | 301 | "@electron/get": ["@electron/get@2.0.3", "", { "dependencies": { "debug": "^4.1.1", "env-paths": "^2.2.0", "fs-extra": "^8.1.0", "got": "^11.8.5", "progress": "^2.0.3", "semver": "^6.2.0", "sumchecker": "^3.0.1" }, "optionalDependencies": { "global-agent": "^3.0.0" } }, "sha512-Qkzpg2s9GnVV2I2BjRksUi43U5e6+zaQMcjoJy0C+C5oxaKl+fmckGDQFtRpZpZV0NQekuZZ+tGz7EA9TVnQtQ=="], |
| 302 | 302 | ||
| ... | @@ -1018,7 +1018,7 @@ | ... | @@ -1018,7 +1018,7 @@ |
| 1018 | 1018 | ||
| 1019 | "dts-resolver": ["dts-resolver@2.1.3", "", { "peerDependencies": { "oxc-resolver": ">=11.0.0" }, "optionalPeers": ["oxc-resolver"] }, "sha512-bihc7jPC90VrosXNzK0LTE2cuLP6jr0Ro8jk+kMugHReJVLIpHz/xadeq3MhuwyO4TD4OA3L1Q8pBBFRc08Tsw=="], | 1019 | "dts-resolver": ["dts-resolver@2.1.3", "", { "peerDependencies": { "oxc-resolver": ">=11.0.0" }, "optionalPeers": ["oxc-resolver"] }, "sha512-bihc7jPC90VrosXNzK0LTE2cuLP6jr0Ro8jk+kMugHReJVLIpHz/xadeq3MhuwyO4TD4OA3L1Q8pBBFRc08Tsw=="], |
| 1020 | 1020 | ||
| 1021 | "effect": ["effect@4.0.0-beta.43", "", { "dependencies": { "@standard-schema/spec": "^1.1.0", "fast-check": "^4.5.3", "find-my-way-ts": "^0.1.6", "ini": "^6.0.0", "kubernetes-types": "^1.30.0", "msgpackr": "^1.11.8", "multipasta": "^0.2.7", "toml": "^3.0.0", "uuid": "^13.0.0", "yaml": "^2.8.2" } }, "sha512-AJYyDimIwJOn87uUz/JzmgDc5GfjxJbXvEbTvNzMa+M3Uer344bLo/O5mMRkqc1vBleA+Ygs4+dbE3QsqOkKTQ=="], | 1021 | "effect": ["effect@4.0.0-beta.45", "", { "dependencies": { "@standard-schema/spec": "^1.1.0", "fast-check": "^4.5.3", "find-my-way-ts": "^0.1.6", "ini": "^6.0.0", "kubernetes-types": "^1.30.0", "msgpackr": "^1.11.8", "multipasta": "^0.2.7", "toml": "^3.0.0", "uuid": "^13.0.0", "yaml": "^2.8.2" } }, "sha512-vvNrUWqnzBIW1hRMa+zw0CLRW6HLgdu7hQ6K7PT/rS+UY/73Ma11O+Oi9oc9zwL8KcN37M47UDseAdlF0bGNWw=="], |
| 1022 | 1022 | ||
| 1023 | "electron": ["electron@40.6.0", "", { "dependencies": { "@electron/get": "^2.0.0", "@types/node": "^24.9.0", "extract-zip": "^2.0.1" }, "bin": { "electron": "cli.js" } }, "sha512-ett8W+yOFGDuM0vhJMamYSkrbV3LoaffzJd9GfjI96zRAxyrNqUSKqBpf/WGbQCweDxX2pkUCUfrv4wwKpsFZA=="], | 1023 | "electron": ["electron@40.6.0", "", { "dependencies": { "@electron/get": "^2.0.0", "@types/node": "^24.9.0", "extract-zip": "^2.0.1" }, "bin": { "electron": "cli.js" } }, "sha512-ett8W+yOFGDuM0vhJMamYSkrbV3LoaffzJd9GfjI96zRAxyrNqUSKqBpf/WGbQCweDxX2pkUCUfrv4wwKpsFZA=="], |
| 1024 | 1024 |
package.json+7-7| ... | @@ -8,13 +8,13 @@ | ... | @@ -8,13 +8,13 @@ |
| 8 | "scripts" | 8 | "scripts" |
| 9 | ], | 9 | ], |
| 10 | "catalog": { | 10 | "catalog": { |
| 11 | "effect": "4.0.0-beta.43", | 11 | "effect": "4.0.0-beta.45", |
| 12 | "@effect/atom-react": "4.0.0-beta.43", | 12 | "@effect/atom-react": "4.0.0-beta.45", |
| 13 | "@effect/platform-bun": "4.0.0-beta.43", | 13 | "@effect/platform-bun": "4.0.0-beta.45", |
| 14 | "@effect/platform-node": "4.0.0-beta.43", | 14 | "@effect/platform-node": "4.0.0-beta.45", |
| 15 | "@effect/platform-node-shared": "4.0.0-beta.43", | 15 | "@effect/platform-node-shared": "4.0.0-beta.45", |
| 16 | "@effect/sql-sqlite-bun": "4.0.0-beta.43", | 16 | "@effect/sql-sqlite-bun": "4.0.0-beta.45", |
| 17 | "@effect/vitest": "4.0.0-beta.43", | 17 | "@effect/vitest": "4.0.0-beta.45", |
| 18 | "@effect/language-service": "0.84.2", | 18 | "@effect/language-service": "0.84.2", |
| 19 | "@types/bun": "^1.3.9", | 19 | "@types/bun": "^1.3.9", |
| 20 | "@types/node": "^24.10.13", | 20 | "@types/node": "^24.10.13", |
packages/client-runtime/src/knownEnvironment.test.ts+5-5| ... | @@ -61,9 +61,9 @@ describe("known environment bootstrap helpers", () => { | ... | @@ -61,9 +61,9 @@ describe("known environment bootstrap helpers", () => { |
| 61 | }); | 61 | }); |
| 62 | 62 | ||
| 63 | describe("scoped refs", () => { | 63 | describe("scoped refs", () => { |
| 64 | const environmentId = EnvironmentId.makeUnsafe("environment-test"); | 64 | const environmentId = EnvironmentId.make("environment-test"); |
| 65 | const projectRef = scopeProjectRef(environmentId, ProjectId.makeUnsafe("project-1")); | 65 | const projectRef = scopeProjectRef(environmentId, ProjectId.make("project-1")); |
| 66 | const threadRef = scopeThreadRef(environmentId, ThreadId.makeUnsafe("thread-1")); | 66 | const threadRef = scopeThreadRef(environmentId, ThreadId.make("thread-1")); |
| 67 | 67 | ||
| 68 | it("builds stable scoped project and thread keys", () => { | 68 | it("builds stable scoped project and thread keys", () => { |
| 69 | expect(scopedRefKey(projectRef)).toBe("environment-test:project-1"); | 69 | expect(scopedRefKey(projectRef)).toBe("environment-test:project-1"); |
| ... | @@ -75,11 +75,11 @@ describe("scoped refs", () => { | ... | @@ -75,11 +75,11 @@ describe("scoped refs", () => { |
| 75 | it("returns typed scoped refs", () => { | 75 | it("returns typed scoped refs", () => { |
| 76 | expect(projectRef).toEqual({ | 76 | expect(projectRef).toEqual({ |
| 77 | environmentId, | 77 | environmentId, |
| 78 | projectId: ProjectId.makeUnsafe("project-1"), | 78 | projectId: ProjectId.make("project-1"), |
| 79 | }); | 79 | }); |
| 80 | expect(threadRef).toEqual({ | 80 | expect(threadRef).toEqual({ |
| 81 | environmentId, | 81 | environmentId, |
| 82 | threadId: ThreadId.makeUnsafe("thread-1"), | 82 | threadId: ThreadId.make("thread-1"), |
| 83 | }); | 83 | }); |
| 84 | }); | 84 | }); |
| 85 | 85 |
packages/contracts/src/baseSchemas.ts+3-2| ... | @@ -12,8 +12,9 @@ export type IsoDateTime = typeof IsoDateTime.Type; | ... | @@ -12,8 +12,9 @@ export type IsoDateTime = typeof IsoDateTime.Type; |
| 12 | /** | 12 | /** |
| 13 | * Construct a branded identifier. Enforces non-empty trimmed strings | 13 | * Construct a branded identifier. Enforces non-empty trimmed strings |
| 14 | */ | 14 | */ |
| 15 | const makeEntityId = <Brand extends string>(brand: Brand) => | 15 | const makeEntityId = <Brand extends string>(brand: Brand) => { |
| 16 | TrimmedNonEmptyString.pipe(Schema.brand(brand)); | 16 | return TrimmedNonEmptyString.pipe(Schema.brand(brand)); |
| 17 | }; | ||
| 17 | 18 | ||
| 18 | export const ThreadId = makeEntityId("ThreadId"); | 19 | export const ThreadId = makeEntityId("ThreadId"); |
| 19 | export type ThreadId = typeof ThreadId.Type; | 20 | export type ThreadId = typeof ThreadId.Type; |
packages/contracts/src/environment.ts+2-2| ... | @@ -1,4 +1,4 @@ | ... | @@ -1,4 +1,4 @@ |
| 1 | import { Schema } from "effect"; | 1 | import { Effect, Schema } from "effect"; |
| 2 | 2 | ||
| 3 | import { EnvironmentId, ProjectId, ThreadId, TrimmedNonEmptyString } from "./baseSchemas"; | 3 | import { EnvironmentId, ProjectId, ThreadId, TrimmedNonEmptyString } from "./baseSchemas"; |
| 4 | 4 | ||
| ... | @@ -20,7 +20,7 @@ export const ExecutionEnvironmentPlatform = Schema.Struct({ | ... | @@ -20,7 +20,7 @@ export const ExecutionEnvironmentPlatform = Schema.Struct({ |
| 20 | export type ExecutionEnvironmentPlatform = typeof ExecutionEnvironmentPlatform.Type; | 20 | export type ExecutionEnvironmentPlatform = typeof ExecutionEnvironmentPlatform.Type; |
| 21 | 21 | ||
| 22 | export const ExecutionEnvironmentCapabilities = Schema.Struct({ | 22 | export const ExecutionEnvironmentCapabilities = Schema.Struct({ |
| 23 | repositoryIdentity: Schema.Boolean.pipe(Schema.withDecodingDefault(() => false)), | 23 | repositoryIdentity: Schema.Boolean.pipe(Schema.withDecodingDefault(Effect.succeed(false))), |
| 24 | }); | 24 | }); |
| 25 | export type ExecutionEnvironmentCapabilities = typeof ExecutionEnvironmentCapabilities.Type; | 25 | export type ExecutionEnvironmentCapabilities = typeof ExecutionEnvironmentCapabilities.Type; |
| 26 | 26 |
packages/contracts/src/orchestration.ts+19-15| ... | @@ -1,4 +1,4 @@ | ... | @@ -1,4 +1,4 @@ |
| 1 | import { Option, Schema, SchemaIssue, Struct } from "effect"; | 1 | import { Effect, Option, Schema, SchemaIssue, Struct } from "effect"; |
| 2 | import { ClaudeModelOptions, CodexModelOptions } from "./model"; | 2 | import { ClaudeModelOptions, CodexModelOptions } from "./model"; |
| 3 | import { RepositoryIdentity } from "./environment"; | 3 | import { RepositoryIdentity } from "./environment"; |
| 4 | import { | 4 | import { |
| ... | @@ -177,8 +177,10 @@ export const OrchestrationProposedPlan = Schema.Struct({ | ... | @@ -177,8 +177,10 @@ export const OrchestrationProposedPlan = Schema.Struct({ |
| 177 | id: OrchestrationProposedPlanId, | 177 | id: OrchestrationProposedPlanId, |
| 178 | turnId: Schema.NullOr(TurnId), | 178 | turnId: Schema.NullOr(TurnId), |
| 179 | planMarkdown: TrimmedNonEmptyString, | 179 | planMarkdown: TrimmedNonEmptyString, |
| 180 | implementedAt: Schema.NullOr(IsoDateTime).pipe(Schema.withDecodingDefault(() => null)), | 180 | implementedAt: Schema.NullOr(IsoDateTime).pipe(Schema.withDecodingDefault(Effect.succeed(null))), |
| 181 | implementationThreadId: Schema.NullOr(ThreadId).pipe(Schema.withDecodingDefault(() => null)), | 181 | implementationThreadId: Schema.NullOr(ThreadId).pipe( |
| 182 | Schema.withDecodingDefault(Effect.succeed(null)), | ||
| 183 | ), | ||
| 182 | createdAt: IsoDateTime, | 184 | createdAt: IsoDateTime, |
| 183 | updatedAt: IsoDateTime, | 185 | updatedAt: IsoDateTime, |
| 184 | }); | 186 | }); |
| ... | @@ -204,7 +206,7 @@ export const OrchestrationSession = Schema.Struct({ | ... | @@ -204,7 +206,7 @@ export const OrchestrationSession = Schema.Struct({ |
| 204 | threadId: ThreadId, | 206 | threadId: ThreadId, |
| 205 | status: OrchestrationSessionStatus, | 207 | status: OrchestrationSessionStatus, |
| 206 | providerName: Schema.NullOr(TrimmedNonEmptyString), | 208 | providerName: Schema.NullOr(TrimmedNonEmptyString), |
| 207 | runtimeMode: RuntimeMode.pipe(Schema.withDecodingDefault(() => DEFAULT_RUNTIME_MODE)), | 209 | runtimeMode: RuntimeMode.pipe(Schema.withDecodingDefault(Effect.succeed(DEFAULT_RUNTIME_MODE))), |
| 208 | activeTurnId: Schema.NullOr(TurnId), | 210 | activeTurnId: Schema.NullOr(TurnId), |
| 209 | lastError: Schema.NullOr(TrimmedNonEmptyString), | 211 | lastError: Schema.NullOr(TrimmedNonEmptyString), |
| 210 | updatedAt: IsoDateTime, | 212 | updatedAt: IsoDateTime, |
| ... | @@ -279,17 +281,19 @@ export const OrchestrationThread = Schema.Struct({ | ... | @@ -279,17 +281,19 @@ export const OrchestrationThread = Schema.Struct({ |
| 279 | modelSelection: ModelSelection, | 281 | modelSelection: ModelSelection, |
| 280 | runtimeMode: RuntimeMode, | 282 | runtimeMode: RuntimeMode, |
| 281 | interactionMode: ProviderInteractionMode.pipe( | 283 | interactionMode: ProviderInteractionMode.pipe( |
| 282 | Schema.withDecodingDefault(() => DEFAULT_PROVIDER_INTERACTION_MODE), | 284 | Schema.withDecodingDefault(Effect.succeed(DEFAULT_PROVIDER_INTERACTION_MODE)), |
| 283 | ), | 285 | ), |
| 284 | branch: Schema.NullOr(TrimmedNonEmptyString), | 286 | branch: Schema.NullOr(TrimmedNonEmptyString), |
| 285 | worktreePath: Schema.NullOr(TrimmedNonEmptyString), | 287 | worktreePath: Schema.NullOr(TrimmedNonEmptyString), |
| 286 | latestTurn: Schema.NullOr(OrchestrationLatestTurn), | 288 | latestTurn: Schema.NullOr(OrchestrationLatestTurn), |
| 287 | createdAt: IsoDateTime, | 289 | createdAt: IsoDateTime, |
| 288 | updatedAt: IsoDateTime, | 290 | updatedAt: IsoDateTime, |
| 289 | archivedAt: Schema.NullOr(IsoDateTime).pipe(Schema.withDecodingDefault(() => null)), | 291 | archivedAt: Schema.NullOr(IsoDateTime).pipe(Schema.withDecodingDefault(Effect.succeed(null))), |
| 290 | deletedAt: Schema.NullOr(IsoDateTime), | 292 | deletedAt: Schema.NullOr(IsoDateTime), |
| 291 | messages: Schema.Array(OrchestrationMessage), | 293 | messages: Schema.Array(OrchestrationMessage), |
| 292 | proposedPlans: Schema.Array(OrchestrationProposedPlan).pipe(Schema.withDecodingDefault(() => [])), | 294 | proposedPlans: Schema.Array(OrchestrationProposedPlan).pipe( |
| 295 | Schema.withDecodingDefault(Effect.succeed([])), | ||
| 296 | ), | ||
| 293 | activities: Schema.Array(OrchestrationThreadActivity), | 297 | activities: Schema.Array(OrchestrationThreadActivity), |
| 294 | checkpoints: Schema.Array(OrchestrationCheckpointSummary), | 298 | checkpoints: Schema.Array(OrchestrationCheckpointSummary), |
| 295 | session: Schema.NullOr(OrchestrationSession), | 299 | session: Schema.NullOr(OrchestrationSession), |
| ... | @@ -339,7 +343,7 @@ const ThreadCreateCommand = Schema.Struct({ | ... | @@ -339,7 +343,7 @@ const ThreadCreateCommand = Schema.Struct({ |
| 339 | modelSelection: ModelSelection, | 343 | modelSelection: ModelSelection, |
| 340 | runtimeMode: RuntimeMode, | 344 | runtimeMode: RuntimeMode, |
| 341 | interactionMode: ProviderInteractionMode.pipe( | 345 | interactionMode: ProviderInteractionMode.pipe( |
| 342 | Schema.withDecodingDefault(() => DEFAULT_PROVIDER_INTERACTION_MODE), | 346 | Schema.withDecodingDefault(Effect.succeed(DEFAULT_PROVIDER_INTERACTION_MODE)), |
| 343 | ), | 347 | ), |
| 344 | branch: Schema.NullOr(TrimmedNonEmptyString), | 348 | branch: Schema.NullOr(TrimmedNonEmptyString), |
| 345 | worktreePath: Schema.NullOr(TrimmedNonEmptyString), | 349 | worktreePath: Schema.NullOr(TrimmedNonEmptyString), |
| ... | @@ -427,9 +431,9 @@ export const ThreadTurnStartCommand = Schema.Struct({ | ... | @@ -427,9 +431,9 @@ export const ThreadTurnStartCommand = Schema.Struct({ |
| 427 | }), | 431 | }), |
| 428 | modelSelection: Schema.optional(ModelSelection), | 432 | modelSelection: Schema.optional(ModelSelection), |
| 429 | titleSeed: Schema.optional(TrimmedNonEmptyString), | 433 | titleSeed: Schema.optional(TrimmedNonEmptyString), |
| 430 | runtimeMode: RuntimeMode.pipe(Schema.withDecodingDefault(() => DEFAULT_RUNTIME_MODE)), | 434 | runtimeMode: RuntimeMode.pipe(Schema.withDecodingDefault(Effect.succeed(DEFAULT_RUNTIME_MODE))), |
| 431 | interactionMode: ProviderInteractionMode.pipe( | 435 | interactionMode: ProviderInteractionMode.pipe( |
| 432 | Schema.withDecodingDefault(() => DEFAULT_PROVIDER_INTERACTION_MODE), | 436 | Schema.withDecodingDefault(Effect.succeed(DEFAULT_PROVIDER_INTERACTION_MODE)), |
| 433 | ), | 437 | ), |
| 434 | bootstrap: Schema.optional(ThreadTurnStartBootstrap), | 438 | bootstrap: Schema.optional(ThreadTurnStartBootstrap), |
| 435 | sourceProposedPlan: Schema.optional(SourceProposedPlanReference), | 439 | sourceProposedPlan: Schema.optional(SourceProposedPlanReference), |
| ... | @@ -680,9 +684,9 @@ export const ThreadCreatedPayload = Schema.Struct({ | ... | @@ -680,9 +684,9 @@ export const ThreadCreatedPayload = Schema.Struct({ |
| 680 | projectId: ProjectId, | 684 | projectId: ProjectId, |
| 681 | title: TrimmedNonEmptyString, | 685 | title: TrimmedNonEmptyString, |
| 682 | modelSelection: ModelSelection, | 686 | modelSelection: ModelSelection, |
| 683 | runtimeMode: RuntimeMode.pipe(Schema.withDecodingDefault(() => DEFAULT_RUNTIME_MODE)), | 687 | runtimeMode: RuntimeMode.pipe(Schema.withDecodingDefault(Effect.succeed(DEFAULT_RUNTIME_MODE))), |
| 684 | interactionMode: ProviderInteractionMode.pipe( | 688 | interactionMode: ProviderInteractionMode.pipe( |
| 685 | Schema.withDecodingDefault(() => DEFAULT_PROVIDER_INTERACTION_MODE), | 689 | Schema.withDecodingDefault(Effect.succeed(DEFAULT_PROVIDER_INTERACTION_MODE)), |
| 686 | ), | 690 | ), |
| 687 | branch: Schema.NullOr(TrimmedNonEmptyString), | 691 | branch: Schema.NullOr(TrimmedNonEmptyString), |
| 688 | worktreePath: Schema.NullOr(TrimmedNonEmptyString), | 692 | worktreePath: Schema.NullOr(TrimmedNonEmptyString), |
| ... | @@ -724,7 +728,7 @@ export const ThreadRuntimeModeSetPayload = Schema.Struct({ | ... | @@ -724,7 +728,7 @@ export const ThreadRuntimeModeSetPayload = Schema.Struct({ |
| 724 | export const ThreadInteractionModeSetPayload = Schema.Struct({ | 728 | export const ThreadInteractionModeSetPayload = Schema.Struct({ |
| 725 | threadId: ThreadId, | 729 | threadId: ThreadId, |
| 726 | interactionMode: ProviderInteractionMode.pipe( | 730 | interactionMode: ProviderInteractionMode.pipe( |
| 727 | Schema.withDecodingDefault(() => DEFAULT_PROVIDER_INTERACTION_MODE), | 731 | Schema.withDecodingDefault(Effect.succeed(DEFAULT_PROVIDER_INTERACTION_MODE)), |
| 728 | ), | 732 | ), |
| 729 | updatedAt: IsoDateTime, | 733 | updatedAt: IsoDateTime, |
| 730 | }); | 734 | }); |
| ... | @@ -746,9 +750,9 @@ export const ThreadTurnStartRequestedPayload = Schema.Struct({ | ... | @@ -746,9 +750,9 @@ export const ThreadTurnStartRequestedPayload = Schema.Struct({ |
| 746 | messageId: MessageId, | 750 | messageId: MessageId, |
| 747 | modelSelection: Schema.optional(ModelSelection), | 751 | modelSelection: Schema.optional(ModelSelection), |
| 748 | titleSeed: Schema.optional(TrimmedNonEmptyString), | 752 | titleSeed: Schema.optional(TrimmedNonEmptyString), |
| 749 | runtimeMode: RuntimeMode.pipe(Schema.withDecodingDefault(() => DEFAULT_RUNTIME_MODE)), | 753 | runtimeMode: RuntimeMode.pipe(Schema.withDecodingDefault(Effect.succeed(DEFAULT_RUNTIME_MODE))), |
| 750 | interactionMode: ProviderInteractionMode.pipe( | 754 | interactionMode: ProviderInteractionMode.pipe( |
| 751 | Schema.withDecodingDefault(() => DEFAULT_PROVIDER_INTERACTION_MODE), | 755 | Schema.withDecodingDefault(Effect.succeed(DEFAULT_PROVIDER_INTERACTION_MODE)), |
| 752 | ), | 756 | ), |
| 753 | sourceProposedPlan: Schema.optional(SourceProposedPlanReference), | 757 | sourceProposedPlan: Schema.optional(SourceProposedPlanReference), |
| 754 | createdAt: IsoDateTime, | 758 | createdAt: IsoDateTime, |
packages/contracts/src/providerRuntime.ts+2-2| ... | @@ -1,4 +1,4 @@ | ... | @@ -1,4 +1,4 @@ |
| 1 | import { Option, Schema } from "effect"; | 1 | import { Effect, Schema } from "effect"; |
| 2 | import { | 2 | import { |
| 3 | EventId, | 3 | EventId, |
| 4 | IsoDateTime, | 4 | IsoDateTime, |
| ... | @@ -435,7 +435,7 @@ export const UserInputQuestion = Schema.Struct({ | ... | @@ -435,7 +435,7 @@ export const UserInputQuestion = Schema.Struct({ |
| 435 | question: TrimmedNonEmptyStringSchema, | 435 | question: TrimmedNonEmptyStringSchema, |
| 436 | options: Schema.Array(UserInputQuestionOption), | 436 | options: Schema.Array(UserInputQuestionOption), |
| 437 | multiSelect: Schema.optional(Schema.Boolean).pipe( | 437 | multiSelect: Schema.optional(Schema.Boolean).pipe( |
| 438 | Schema.withConstructorDefault(() => Option.some(false)), | 438 | Schema.withConstructorDefault(Effect.succeed(false)), |
| 439 | ), | 439 | ), |
| 440 | }); | 440 | }); |
| 441 | export type UserInputQuestion = typeof UserInputQuestion.Type; | 441 | export type UserInputQuestion = typeof UserInputQuestion.Type; |
packages/contracts/src/settings.ts+28-24| ... | @@ -24,16 +24,18 @@ export type SidebarThreadSortOrder = typeof SidebarThreadSortOrder.Type; | ... | @@ -24,16 +24,18 @@ export type SidebarThreadSortOrder = typeof SidebarThreadSortOrder.Type; |
| 24 | export const DEFAULT_SIDEBAR_THREAD_SORT_ORDER: SidebarThreadSortOrder = "updated_at"; | 24 | export const DEFAULT_SIDEBAR_THREAD_SORT_ORDER: SidebarThreadSortOrder = "updated_at"; |
| 25 | 25 | ||
| 26 | export const ClientSettingsSchema = Schema.Struct({ | 26 | export const ClientSettingsSchema = Schema.Struct({ |
| 27 | confirmThreadArchive: Schema.Boolean.pipe(Schema.withDecodingDefault(() => false)), | 27 | confirmThreadArchive: Schema.Boolean.pipe(Schema.withDecodingDefault(Effect.succeed(false))), |
| 28 | confirmThreadDelete: Schema.Boolean.pipe(Schema.withDecodingDefault(() => true)), | 28 | confirmThreadDelete: Schema.Boolean.pipe(Schema.withDecodingDefault(Effect.succeed(true))), |
| 29 | diffWordWrap: Schema.Boolean.pipe(Schema.withDecodingDefault(() => false)), | 29 | diffWordWrap: Schema.Boolean.pipe(Schema.withDecodingDefault(Effect.succeed(false))), |
| 30 | sidebarProjectSortOrder: SidebarProjectSortOrder.pipe( | 30 | sidebarProjectSortOrder: SidebarProjectSortOrder.pipe( |
| 31 | Schema.withDecodingDefault(() => DEFAULT_SIDEBAR_PROJECT_SORT_ORDER), | 31 | Schema.withDecodingDefault(Effect.succeed(DEFAULT_SIDEBAR_PROJECT_SORT_ORDER)), |
| 32 | ), | 32 | ), |
| 33 | sidebarThreadSortOrder: SidebarThreadSortOrder.pipe( | 33 | sidebarThreadSortOrder: SidebarThreadSortOrder.pipe( |
| 34 | Schema.withDecodingDefault(() => DEFAULT_SIDEBAR_THREAD_SORT_ORDER), | 34 | Schema.withDecodingDefault(Effect.succeed(DEFAULT_SIDEBAR_THREAD_SORT_ORDER)), |
| 35 | ), | ||
| 36 | timestampFormat: TimestampFormat.pipe( | ||
| 37 | Schema.withDecodingDefault(Effect.succeed(DEFAULT_TIMESTAMP_FORMAT)), | ||
| 35 | ), | 38 | ), |
| 36 | timestampFormat: TimestampFormat.pipe(Schema.withDecodingDefault(() => DEFAULT_TIMESTAMP_FORMAT)), | ||
| 37 | }); | 39 | }); |
| 38 | export type ClientSettings = typeof ClientSettingsSchema.Type; | 40 | export type ClientSettings = typeof ClientSettingsSchema.Type; |
| 39 | 41 | ||
| ... | @@ -53,48 +55,50 @@ const makeBinaryPathSetting = (fallback: string) => | ... | @@ -53,48 +55,50 @@ const makeBinaryPathSetting = (fallback: string) => |
| 53 | encode: (value) => Effect.succeed(value), | 55 | encode: (value) => Effect.succeed(value), |
| 54 | }), | 56 | }), |
| 55 | ), | 57 | ), |
| 56 | Schema.withDecodingDefault(() => fallback), | 58 | Schema.withDecodingDefault(Effect.succeed(fallback)), |
| 57 | ); | 59 | ); |
| 58 | 60 | ||
| 59 | export const CodexSettings = Schema.Struct({ | 61 | export const CodexSettings = Schema.Struct({ |
| 60 | enabled: Schema.Boolean.pipe(Schema.withDecodingDefault(() => true)), | 62 | enabled: Schema.Boolean.pipe(Schema.withDecodingDefault(Effect.succeed(true))), |
| 61 | binaryPath: makeBinaryPathSetting("codex"), | 63 | binaryPath: makeBinaryPathSetting("codex"), |
| 62 | homePath: TrimmedString.pipe(Schema.withDecodingDefault(() => "")), | 64 | homePath: TrimmedString.pipe(Schema.withDecodingDefault(Effect.succeed(""))), |
| 63 | customModels: Schema.Array(Schema.String).pipe(Schema.withDecodingDefault(() => [])), | 65 | customModels: Schema.Array(Schema.String).pipe(Schema.withDecodingDefault(Effect.succeed([]))), |
| 64 | }); | 66 | }); |
| 65 | export type CodexSettings = typeof CodexSettings.Type; | 67 | export type CodexSettings = typeof CodexSettings.Type; |
| 66 | 68 | ||
| 67 | export const ClaudeSettings = Schema.Struct({ | 69 | export const ClaudeSettings = Schema.Struct({ |
| 68 | enabled: Schema.Boolean.pipe(Schema.withDecodingDefault(() => true)), | 70 | enabled: Schema.Boolean.pipe(Schema.withDecodingDefault(Effect.succeed(true))), |
| 69 | binaryPath: makeBinaryPathSetting("claude"), | 71 | binaryPath: makeBinaryPathSetting("claude"), |
| 70 | customModels: Schema.Array(Schema.String).pipe(Schema.withDecodingDefault(() => [])), | 72 | customModels: Schema.Array(Schema.String).pipe(Schema.withDecodingDefault(Effect.succeed([]))), |
| 71 | }); | 73 | }); |
| 72 | export type ClaudeSettings = typeof ClaudeSettings.Type; | 74 | export type ClaudeSettings = typeof ClaudeSettings.Type; |
| 73 | 75 | ||
| 74 | export const ObservabilitySettings = Schema.Struct({ | 76 | export const ObservabilitySettings = Schema.Struct({ |
| 75 | otlpTracesUrl: TrimmedString.pipe(Schema.withDecodingDefault(() => "")), | 77 | otlpTracesUrl: TrimmedString.pipe(Schema.withDecodingDefault(Effect.succeed(""))), |
| 76 | otlpMetricsUrl: TrimmedString.pipe(Schema.withDecodingDefault(() => "")), | 78 | otlpMetricsUrl: TrimmedString.pipe(Schema.withDecodingDefault(Effect.succeed(""))), |
| 77 | }); | 79 | }); |
| 78 | export type ObservabilitySettings = typeof ObservabilitySettings.Type; | 80 | export type ObservabilitySettings = typeof ObservabilitySettings.Type; |
| 79 | 81 | ||
| 80 | export const ServerSettings = Schema.Struct({ | 82 | export const ServerSettings = Schema.Struct({ |
| 81 | enableAssistantStreaming: Schema.Boolean.pipe(Schema.withDecodingDefault(() => false)), | 83 | enableAssistantStreaming: Schema.Boolean.pipe(Schema.withDecodingDefault(Effect.succeed(false))), |
| 82 | defaultThreadEnvMode: ThreadEnvMode.pipe( | 84 | defaultThreadEnvMode: ThreadEnvMode.pipe( |
| 83 | Schema.withDecodingDefault(() => "local" as const satisfies ThreadEnvMode), | 85 | Schema.withDecodingDefault(Effect.succeed("local" as const satisfies ThreadEnvMode)), |
| 84 | ), | 86 | ), |
| 85 | textGenerationModelSelection: ModelSelection.pipe( | 87 | textGenerationModelSelection: ModelSelection.pipe( |
| 86 | Schema.withDecodingDefault(() => ({ | 88 | Schema.withDecodingDefault( |
| 87 | provider: "codex" as const, | 89 | Effect.succeed({ |
| 88 | model: DEFAULT_GIT_TEXT_GENERATION_MODEL_BY_PROVIDER.codex, | 90 | provider: "codex" as const, |
| 89 | })), | 91 | model: DEFAULT_GIT_TEXT_GENERATION_MODEL_BY_PROVIDER.codex, |
| 92 | }), | ||
| 93 | ), | ||
| 90 | ), | 94 | ), |
| 91 | 95 | ||
| 92 | // Provider specific settings | 96 | // Provider specific settings |
| 93 | providers: Schema.Struct({ | 97 | providers: Schema.Struct({ |
| 94 | codex: CodexSettings.pipe(Schema.withDecodingDefault(() => ({}))), | 98 | codex: CodexSettings.pipe(Schema.withDecodingDefault(Effect.succeed({}))), |
| 95 | claudeAgent: ClaudeSettings.pipe(Schema.withDecodingDefault(() => ({}))), | 99 | claudeAgent: ClaudeSettings.pipe(Schema.withDecodingDefault(Effect.succeed({}))), |
| 96 | }).pipe(Schema.withDecodingDefault(() => ({}))), | 100 | }).pipe(Schema.withDecodingDefault(Effect.succeed({}))), |
| 97 | observability: ObservabilitySettings.pipe(Schema.withDecodingDefault(() => ({}))), | 101 | observability: ObservabilitySettings.pipe(Schema.withDecodingDefault(Effect.succeed({}))), |
| 98 | }); | 102 | }); |
| 99 | export type ServerSettings = typeof ServerSettings.Type; | 103 | export type ServerSettings = typeof ServerSettings.Type; |
| 100 | 104 |
packages/contracts/src/terminal.ts+2-2| ... | @@ -1,4 +1,4 @@ | ... | @@ -1,4 +1,4 @@ |
| 1 | import { Schema } from "effect"; | 1 | import { Effect, Schema } from "effect"; |
| 2 | import { TrimmedNonEmptyString } from "./baseSchemas"; | 2 | import { TrimmedNonEmptyString } from "./baseSchemas"; |
| 3 | 3 | ||
| 4 | export const DEFAULT_TERMINAL_ID = "default"; | 4 | export const DEFAULT_TERMINAL_ID = "default"; |
| ... | @@ -20,7 +20,7 @@ const TerminalEnvSchema = Schema.Record(TerminalEnvKeySchema, TerminalEnvValueSc | ... | @@ -20,7 +20,7 @@ const TerminalEnvSchema = Schema.Record(TerminalEnvKeySchema, TerminalEnvValueSc |
| 20 | ); | 20 | ); |
| 21 | 21 | ||
| 22 | const TerminalIdWithDefaultSchema = TerminalIdSchema.pipe( | 22 | const TerminalIdWithDefaultSchema = TerminalIdSchema.pipe( |
| 23 | Schema.withDecodingDefault(() => DEFAULT_TERMINAL_ID), | 23 | Schema.withDecodingDefault(Effect.succeed(DEFAULT_TERMINAL_ID)), |
| 24 | ); | 24 | ); |
| 25 | 25 | ||
| 26 | export const TerminalThreadInput = Schema.Struct({ | 26 | export const TerminalThreadInput = Schema.Struct({ |
packages/shared/src/Net.ts+2-2| ... | @@ -1,6 +1,6 @@ | ... | @@ -1,6 +1,6 @@ |
| 1 | import * as Net from "node:net"; | 1 | import * as Net from "node:net"; |
| 2 | 2 | ||
| 3 | import { Data, Effect, Layer, ServiceMap } from "effect"; | 3 | import { Data, Effect, Layer, Context } from "effect"; |
| 4 | 4 | ||
| 5 | export class NetError extends Data.TaggedError("NetError")<{ | 5 | export class NetError extends Data.TaggedError("NetError")<{ |
| 6 | readonly message: string; | 6 | readonly message: string; |
| ... | @@ -85,7 +85,7 @@ export interface NetServiceShape { | ... | @@ -85,7 +85,7 @@ export interface NetServiceShape { |
| 85 | /** | 85 | /** |
| 86 | * NetService - Service tag for startup networking helpers. | 86 | * NetService - Service tag for startup networking helpers. |
| 87 | */ | 87 | */ |
| 88 | export class NetService extends ServiceMap.Service<NetService, NetServiceShape>()( | 88 | export class NetService extends Context.Service<NetService, NetServiceShape>()( |
| 89 | "@t3tools/shared/Net/NetService", | 89 | "@t3tools/shared/Net/NetService", |
| 90 | ) { | 90 | ) { |
| 91 | static readonly layer = Layer.sync(NetService, () => { | 91 | static readonly layer = Layer.sync(NetService, () => { |
scripts/build-desktop-artifact.test.ts created+45| ... | @@ -0,0 +1,45 @@ | ||
| 1 | import * as NodeServices from "@effect/platform-node/NodeServices"; | ||
| 2 | import { assert, it } from "@effect/vitest"; | ||
| 3 | import { ConfigProvider, Effect, Option } from "effect"; | ||
| 4 | |||
| 5 | import { resolveBuildOptions } from "./build-desktop-artifact.ts"; | ||
| 6 | |||
| 7 | it.layer(NodeServices.layer)("build-desktop-artifact", (it) => { | ||
| 8 | it.effect("preserves explicit false boolean flags over true env defaults", () => | ||
| 9 | Effect.gen(function* () { | ||
| 10 | const resolved = yield* resolveBuildOptions({ | ||
| 11 | platform: Option.some("mac"), | ||
| 12 | target: Option.none(), | ||
| 13 | arch: Option.some("arm64"), | ||
| 14 | buildVersion: Option.none(), | ||
| 15 | outputDir: Option.some("release-test"), | ||
| 16 | skipBuild: Option.some(false), | ||
| 17 | keepStage: Option.some(false), | ||
| 18 | signed: Option.some(false), | ||
| 19 | verbose: Option.some(false), | ||
| 20 | mockUpdates: Option.some(false), | ||
| 21 | mockUpdateServerPort: Option.none(), | ||
| 22 | }).pipe( | ||
| 23 | Effect.provide( | ||
| 24 | ConfigProvider.layer( | ||
| 25 | ConfigProvider.fromEnv({ | ||
| 26 | env: { | ||
| 27 | T3CODE_DESKTOP_SKIP_BUILD: "true", | ||
| 28 | T3CODE_DESKTOP_KEEP_STAGE: "true", | ||
| 29 | T3CODE_DESKTOP_SIGNED: "true", | ||
| 30 | T3CODE_DESKTOP_VERBOSE: "true", | ||
| 31 | T3CODE_DESKTOP_MOCK_UPDATES: "true", | ||
| 32 | }, | ||
| 33 | }), | ||
| 34 | ), | ||
| 35 | ), | ||
| 36 | ); | ||
| 37 | |||
| 38 | assert.equal(resolved.skipBuild, false); | ||
| 39 | assert.equal(resolved.keepStage, false); | ||
| 40 | assert.equal(resolved.signed, false); | ||
| 41 | assert.equal(resolved.verbose, false); | ||
| 42 | assert.equal(resolved.mockUpdates, false); | ||
| 43 | }), | ||
| 44 | ); | ||
| 45 | }); | ||
scripts/build-desktop-artifact.ts+11-7| ... | @@ -214,11 +214,13 @@ const BuildEnvConfig = Config.all({ | ... | @@ -214,11 +214,13 @@ const BuildEnvConfig = Config.all({ |
| 214 | }); | 214 | }); |
| 215 | 215 | ||
| 216 | const resolveBooleanFlag = (flag: Option.Option<boolean>, envValue: boolean) => | 216 | const resolveBooleanFlag = (flag: Option.Option<boolean>, envValue: boolean) => |
| 217 | Option.getOrElse(Option.filter(flag, Boolean), () => envValue); | 217 | Option.getOrElse(flag, () => envValue); |
| 218 | const mergeOptions = <A>(a: Option.Option<A>, b: Option.Option<A>, defaultValue: A) => | 218 | const mergeOptions = <A>(a: Option.Option<A>, b: Option.Option<A>, defaultValue: A) => |
| 219 | Option.getOrElse(a, () => Option.getOrElse(b, () => defaultValue)); | 219 | Option.getOrElse(a, () => Option.getOrElse(b, () => defaultValue)); |
| 220 | 220 | ||
| 221 | const resolveBuildOptions = Effect.fn("resolveBuildOptions")(function* (input: BuildCliInput) { | 221 | export const resolveBuildOptions = Effect.fn("resolveBuildOptions")(function* ( |
| 222 | input: BuildCliInput, | ||
| 223 | ) { | ||
| 222 | const path = yield* Path.Path; | 224 | const path = yield* Path.Path; |
| 223 | const repoRoot = yield* RepoRoot; | 225 | const repoRoot = yield* RepoRoot; |
| 224 | const env = yield* BuildEnvConfig.asEffect(); | 226 | const env = yield* BuildEnvConfig.asEffect(); |
| ... | @@ -838,8 +840,10 @@ const buildDesktopArtifactCli = Command.make("build-desktop-artifact", { | ... | @@ -838,8 +840,10 @@ const buildDesktopArtifactCli = Command.make("build-desktop-artifact", { |
| 838 | 840 | ||
| 839 | const cliRuntimeLayer = Layer.mergeAll(Logger.layer([Logger.consolePretty()]), NodeServices.layer); | 841 | const cliRuntimeLayer = Layer.mergeAll(Logger.layer([Logger.consolePretty()]), NodeServices.layer); |
| 840 | 842 | ||
| 841 | Command.run(buildDesktopArtifactCli, { version: "0.0.0" }).pipe( | 843 | if (import.meta.main) { |
| 842 | Effect.scoped, | 844 | Command.run(buildDesktopArtifactCli, { version: "0.0.0" }).pipe( |
| 843 | Effect.provide(cliRuntimeLayer), | 845 | Effect.scoped, |
| 844 | NodeRuntime.runMain, | 846 | Effect.provide(cliRuntimeLayer), |
| 845 | ); | 847 | NodeRuntime.runMain, |
| 848 | ); | ||
| 849 | } |
scripts/dev-runner.test.ts+3-1| ... | @@ -121,7 +121,9 @@ it.layer(NodeServices.layer)("dev-runner", (it) => { | ... | @@ -121,7 +121,9 @@ it.layer(NodeServices.layer)("dev-runner", (it) => { |
| 121 | Effect.gen(function* () { | 121 | Effect.gen(function* () { |
| 122 | const env = yield* createDevRunnerEnv({ | 122 | const env = yield* createDevRunnerEnv({ |
| 123 | mode: "dev", | 123 | mode: "dev", |
| 124 | baseEnv: {}, | 124 | baseEnv: { |
| 125 | T3CODE_LOG_WS_EVENTS: "1", | ||
| 126 | }, | ||
| 125 | serverOffset: 0, | 127 | serverOffset: 0, |
| 126 | webOffset: 0, | 128 | webOffset: 0, |
| 127 | t3Home: undefined, | 129 | t3Home: undefined, |
scripts/dev-runner.ts+3-44| ... | @@ -356,35 +356,6 @@ interface DevRunnerCliInput { | ... | @@ -356,35 +356,6 @@ interface DevRunnerCliInput { |
| 356 | readonly turboArgs: ReadonlyArray<string>; | 356 | readonly turboArgs: ReadonlyArray<string>; |
| 357 | } | 357 | } |
| 358 | 358 | ||
| 359 | const readOptionalBooleanEnv = (name: string): boolean | undefined => { | ||
| 360 | const value = process.env[name]; | ||
| 361 | if (value === undefined) { | ||
| 362 | return undefined; | ||
| 363 | } | ||
| 364 | if (value === "1" || value.toLowerCase() === "true") { | ||
| 365 | return true; | ||
| 366 | } | ||
| 367 | if (value === "0" || value.toLowerCase() === "false") { | ||
| 368 | return false; | ||
| 369 | } | ||
| 370 | return undefined; | ||
| 371 | }; | ||
| 372 | |||
| 373 | const resolveOptionalBooleanOverride = ( | ||
| 374 | explicitValue: boolean | undefined, | ||
| 375 | envValue: boolean | undefined, | ||
| 376 | ): boolean | undefined => { | ||
| 377 | if (explicitValue === true) { | ||
| 378 | return true; | ||
| 379 | } | ||
| 380 | |||
| 381 | if (explicitValue === false) { | ||
| 382 | return envValue; | ||
| 383 | } | ||
| 384 | |||
| 385 | return envValue; | ||
| 386 | }; | ||
| 387 | |||
| 388 | export function runDevRunnerWithInput(input: DevRunnerCliInput) { | 359 | export function runDevRunnerWithInput(input: DevRunnerCliInput) { |
| 389 | return Effect.gen(function* () { | 360 | return Effect.gen(function* () { |
| 390 | const { portOffset, devInstance } = yield* OffsetConfig.asEffect().pipe( | 361 | const { portOffset, devInstance } = yield* OffsetConfig.asEffect().pipe( |
| ... | @@ -406,12 +377,6 @@ export function runDevRunnerWithInput(input: DevRunnerCliInput) { | ... | @@ -406,12 +377,6 @@ export function runDevRunnerWithInput(input: DevRunnerCliInput) { |
| 406 | }), | 377 | }), |
| 407 | }); | 378 | }); |
| 408 | 379 | ||
| 409 | const envOverrides = { | ||
| 410 | noBrowser: readOptionalBooleanEnv("T3CODE_NO_BROWSER"), | ||
| 411 | autoBootstrapProjectFromCwd: readOptionalBooleanEnv("T3CODE_AUTO_BOOTSTRAP_PROJECT_FROM_CWD"), | ||
| 412 | logWebSocketEvents: readOptionalBooleanEnv("T3CODE_LOG_WS_EVENTS"), | ||
| 413 | }; | ||
| 414 | |||
| 415 | const { serverOffset, webOffset } = yield* resolveModePortOffsets({ | 380 | const { serverOffset, webOffset } = yield* resolveModePortOffsets({ |
| 416 | mode: input.mode, | 381 | mode: input.mode, |
| 417 | startOffset: offset, | 382 | startOffset: offset, |
| ... | @@ -425,15 +390,9 @@ export function runDevRunnerWithInput(input: DevRunnerCliInput) { | ... | @@ -425,15 +390,9 @@ export function runDevRunnerWithInput(input: DevRunnerCliInput) { |
| 425 | serverOffset, | 390 | serverOffset, |
| 426 | webOffset, | 391 | webOffset, |
| 427 | t3Home: input.t3Home, | 392 | t3Home: input.t3Home, |
| 428 | noBrowser: resolveOptionalBooleanOverride(input.noBrowser, envOverrides.noBrowser), | 393 | noBrowser: input.noBrowser, |
| 429 | autoBootstrapProjectFromCwd: resolveOptionalBooleanOverride( | 394 | autoBootstrapProjectFromCwd: input.autoBootstrapProjectFromCwd, |
| 430 | input.autoBootstrapProjectFromCwd, | 395 | logWebSocketEvents: input.logWebSocketEvents, |
| 431 | envOverrides.autoBootstrapProjectFromCwd, | ||
| 432 | ), | ||
| 433 | logWebSocketEvents: resolveOptionalBooleanOverride( | ||
| 434 | input.logWebSocketEvents, | ||
| 435 | envOverrides.logWebSocketEvents, | ||
| 436 | ), | ||
| 437 | host: input.host, | 396 | host: input.host, |
| 438 | port: input.port, | 397 | port: input.port, |
| 439 | devUrl: input.devUrl, | 398 | devUrl: input.devUrl, |