authorgravatar for 92423096+nateEc@users.noreply.github.comYukun Shan <92423096+nateEc@users.noreply.github.com> 2026-09-01 01:21:36+08:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2026-08-31 10:21:36-07:00
log2921050c698fb195e2f5590b7cfab8fdfe0ec729
tree5bc35e34d3a43b6706feaa0a422be1f7bee74569
parentad38700ac678b8c8a0310d434a44d94a7ee6a47f
signature Signed by PGP key B5690EEEBB952194

fix(contracts): accept CLI event origins (#8905)


2 files changed, 7 insertions(+), 3 deletions(-)

apps/server/src/persistence/Layers/OrchestrationEventStore.test.ts+5-1
...@@ -17,7 +17,7 @@ const layer = it.layer(...@@ -17,7 +17,7 @@ const layer = it.layer(
17);17);
1818
19layer("OrchestrationEventStore", (it) => {19layer("OrchestrationEventStore", (it) => {
20 it.effect("stores json columns as strings and replays decoded events", () =>20 it.effect("stores json columns as strings and replays CLI-origin events", () =>
21 Effect.gen(function* () {21 Effect.gen(function* () {
22 const eventStore = yield* OrchestrationEventStore;22 const eventStore = yield* OrchestrationEventStore;
23 const sql = yield* SqlClient.SqlClient;23 const sql = yield* SqlClient.SqlClient;
...@@ -34,6 +34,9 @@ layer("OrchestrationEventStore", (it) => {...@@ -34,6 +34,9 @@ layer("OrchestrationEventStore", (it) => {
34 correlationId: CommandId.make("cmd-store-roundtrip"),34 correlationId: CommandId.make("cmd-store-roundtrip"),
35 metadata: {35 metadata: {
36 adapterKey: "codex",36 adapterKey: "codex",
37 origin: {
38 surface: "cli",
39 },
37 },40 },
38 payload: {41 payload: {
39 projectId: ProjectId.make("project-roundtrip"),42 projectId: ProjectId.make("project-roundtrip"),
...@@ -66,6 +69,7 @@ layer("OrchestrationEventStore", (it) => {...@@ -66,6 +69,7 @@ layer("OrchestrationEventStore", (it) => {
66 assert.equal(replayed.length, 1);69 assert.equal(replayed.length, 1);
67 assert.equal(replayed[0]?.type, "project.created");70 assert.equal(replayed[0]?.type, "project.created");
68 assert.equal(replayed[0]?.metadata.adapterKey, "codex");71 assert.equal(replayed[0]?.metadata.adapterKey, "codex");
72 assert.deepEqual(replayed[0]?.metadata.origin, { surface: "cli" });
69 }),73 }),
70 );74 );
7175
packages/contracts/src/baseSchemas.ts+2-2
...@@ -86,12 +86,12 @@ export const RpcClientId = NonNegativeInt.pipe(Schema.brand("RpcClientId"));...@@ -86,12 +86,12 @@ export const RpcClientId = NonNegativeInt.pipe(Schema.brand("RpcClientId"));
86export type RpcClientId = typeof RpcClientId.Type;86export type RpcClientId = typeof RpcClientId.Type;
8787
88/**88/**
89 * Which client app a connection comes from. Unlike89 * Which client surface a connection or command comes from. Unlike
90 * `AuthClientMetadataDeviceType` (a UA-style device class where web and90 * `AuthClientMetadataDeviceType` (a UA-style device class where web and
91 * desktop are both "desktop"), this names the actual product surface.91 * desktop are both "desktop"), this names the actual product surface.
92 * Optional everywhere it appears: old clients never send it.92 * Optional everywhere it appears: old clients never send it.
93 */93 */
94export const ClientSurface = Schema.Literals(["web", "desktop", "mobile"]);94export const ClientSurface = Schema.Literals(["web", "desktop", "mobile", "cli"]);
95export type ClientSurface = typeof ClientSurface.Type;95export type ClientSurface = typeof ClientSurface.Type;
9696
97export const ClientOs = Schema.Literals([97export const ClientOs = Schema.Literals([