@opencode/protocol 0.0.0-dev-21085 → 0.0.0-dev-21090

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/api.d.ts CHANGED
@@ -2,6 +2,7 @@ import { Context } from "effect";
2
2
  import { HttpApi, HttpApiGroup, HttpApiMiddleware } from "effect/http-api";
3
3
  import { SchemaErrorMiddleware } from "./middleware/schema-error.js";
4
4
  import { GenerateGroup } from "./groups/generate.js";
5
+ import { VoiceGroup } from "./groups/voice.js";
5
6
  import { MessageGroup } from "./groups/message.js";
6
7
  import { ModelGroup } from "./groups/model.js";
7
8
  import { ProviderGroup } from "./groups/provider.js";
@@ -39,7 +40,7 @@ type SessionGroups<SessionLocationId extends HttpApiMiddleware.AnyId, SessionLoc
39
40
  type FormGroups<LocationId extends HttpApiMiddleware.AnyId, LocationService> = ReturnType<typeof makeFormGroup<LocationId, LocationService>>;
40
41
  type LocationGroup<LocationId extends HttpApiMiddleware.AnyId, LocationService> = ReturnType<typeof makeLocationGroup<LocationId, LocationService>>;
41
42
  type MixedMiddlewareGroups<LocationId extends HttpApiMiddleware.AnyId, LocationService, SessionLocationId extends HttpApiMiddleware.AnyId, SessionLocationService> = ReturnType<typeof makePermissionGroup<LocationId, LocationService, SessionLocationId, SessionLocationService>>;
42
- type ApiGroups<LocationId extends HttpApiMiddleware.AnyId, LocationService, FormLocationId extends HttpApiMiddleware.AnyId, FormLocationService, SessionLocationId extends HttpApiMiddleware.AnyId, SessionLocationService, Event extends HttpApiGroup.Constraint> = typeof ServerGroup | typeof DebugGroup | typeof MigrationGroup | typeof WorktreeGroup | typeof GenerateGroup | typeof PersistentPtyGroup | typeof CredentialGroup | LocationGroups<LocationId> | LocationGroup<LocationId, LocationService> | PtyGroups<LocationId, LocationService> | FormGroups<LocationId, LocationService> | SessionGroups<SessionLocationId, SessionLocationService, FormLocationId, FormLocationService> | MixedMiddlewareGroups<LocationId, LocationService, SessionLocationId, SessionLocationService> | Event;
43
+ type ApiGroups<LocationId extends HttpApiMiddleware.AnyId, LocationService, FormLocationId extends HttpApiMiddleware.AnyId, FormLocationService, SessionLocationId extends HttpApiMiddleware.AnyId, SessionLocationService, Event extends HttpApiGroup.Constraint> = typeof ServerGroup | typeof DebugGroup | typeof MigrationGroup | typeof WorktreeGroup | typeof GenerateGroup | typeof VoiceGroup | typeof PersistentPtyGroup | typeof CredentialGroup | LocationGroups<LocationId> | LocationGroup<LocationId, LocationService> | PtyGroups<LocationId, LocationService> | FormGroups<LocationId, LocationService> | SessionGroups<SessionLocationId, SessionLocationService, FormLocationId, FormLocationService> | MixedMiddlewareGroups<LocationId, LocationService, SessionLocationId, SessionLocationService> | Event;
43
44
  type EventGroupFor<Definitions extends ReadonlyArray<Definition>> = ReturnType<typeof makeEventGroup<Definitions>>;
44
45
  export type Api<LocationId extends HttpApiMiddleware.AnyId, LocationService, FormLocationId extends HttpApiMiddleware.AnyId, FormLocationService, SessionLocationId extends HttpApiMiddleware.AnyId, SessionLocationService, Event extends HttpApiGroup.Constraint> = HttpApi.HttpApi<"server", HttpApiGroup.AddMiddleware<HttpApiGroup.AddMiddleware<ApiGroups<LocationId, LocationService, FormLocationId, FormLocationService, SessionLocationId, SessionLocationService, Event>, Authorization>, SchemaErrorMiddleware>>;
45
46
  export declare const makeApi: <const Definitions extends ReadonlyArray<Definition>, LocationId extends HttpApiMiddleware.AnyId, LocationService, FormLocationId extends HttpApiMiddleware.AnyId, FormLocationService, SessionLocationId extends HttpApiMiddleware.AnyId, SessionLocationService>(options: {
package/dist/api.js CHANGED
@@ -2,6 +2,7 @@ import { Context } from "effect";
2
2
  import { HttpApi, HttpApiGroup, HttpApiMiddleware, OpenApi } from "effect/http-api";
3
3
  import { SchemaErrorMiddleware } from "./middleware/schema-error.js";
4
4
  import { GenerateGroup } from "./groups/generate.js";
5
+ import { VoiceGroup } from "./groups/voice.js";
5
6
  import { MessageGroup } from "./groups/message.js";
6
7
  import { ModelGroup } from "./groups/model.js";
7
8
  import { ProviderGroup } from "./groups/provider.js";
@@ -42,6 +43,7 @@ const makeApiFromGroup = (eventGroup, locationMiddleware, formLocationMiddleware
42
43
  .add(MessageGroup)
43
44
  .add(ModelGroup.middleware(locationMiddleware))
44
45
  .add(GenerateGroup)
46
+ .add(VoiceGroup)
45
47
  .add(ProviderGroup.middleware(locationMiddleware))
46
48
  .add(IntegrationGroup.middleware(locationMiddleware))
47
49
  .add(McpGroup.middleware(locationMiddleware))
package/dist/client.d.ts CHANGED
@@ -36,6 +36,7 @@ export declare const groupNames: {
36
36
  readonly "server.message": "message";
37
37
  readonly "server.model": "model";
38
38
  readonly "server.generate": "generate";
39
+ readonly "server.voice": "voice";
39
40
  readonly "server.provider": "provider";
40
41
  readonly "server.integration": "integration";
41
42
  readonly "server.websearch": "websearch";
package/dist/client.js CHANGED
@@ -23,6 +23,7 @@ export const groupNames = {
23
23
  "server.message": "message",
24
24
  "server.model": "model",
25
25
  "server.generate": "generate",
26
+ "server.voice": "voice",
26
27
  "server.provider": "provider",
27
28
  "server.integration": "integration",
28
29
  "server.websearch": "websearch",
@@ -1,63 +1,43 @@
1
1
  import { PromptInput } from "@opencode/schema/prompt-input";
2
+ import { Session } from "@opencode/schema/session";
2
3
  import { InstructionEntry } from "@opencode/schema/instruction-entry";
3
4
  import { Event } from "@opencode/schema/event";
4
- import { Context, Effect, Schema } from "effect";
5
+ import { Context, Schema } from "effect";
5
6
  import { HttpApiEndpoint, HttpApiGroup, HttpApiMiddleware, HttpApiSchema } from "effect/http-api";
6
7
  import { ConflictError, LocationNotFoundError, CommandExecutionError, CommandNotFoundError, FormAlreadySettledError, FormInvalidAnswerError, FormNotFoundError, InvalidCursorError, InvalidRequestError, MessageNotFoundError, ServiceUnavailableError, SessionBusyError, SessionNotFoundError, SkillNotFoundError, UnknownError } from "../errors.js";
7
- declare const SessionsCursorInput: Schema.Union<readonly [Schema.Struct<{
8
- readonly directory: Schema.brand<Schema.String, "AbsolutePath">;
9
- readonly parentID: Schema.optional<Schema.Union<readonly [Schema.brand<Schema.String, "SessionID"> & {
10
- create: () => string & import("effect/Brand").Brand<"SessionID">;
11
- descending: (id?: string) => string & import("effect/Brand").Brand<"SessionID">;
12
- }, Schema.decodeTo<Schema.Null, Schema.Literal<"null">, never, never>]>>;
13
- readonly search: Schema.optional<Schema.String>;
14
- readonly order: Schema.optional<Schema.Union<readonly [Schema.Literal<"asc">, Schema.Literal<"desc">]>>;
15
- readonly anchor: Schema.Struct<{
16
- readonly id: Schema.brand<Schema.String, "SessionID"> & {
17
- create: () => string & import("effect/Brand").Brand<"SessionID">;
18
- descending: (id?: string) => string & import("effect/Brand").Brand<"SessionID">;
8
+ export declare const SessionsCursor: Schema.brand<Schema.String, "SessionsCursor"> & {
9
+ make: (input: {
10
+ readonly directory: string & import("effect/Brand").Brand<"AbsolutePath">;
11
+ readonly anchor: {
12
+ readonly id: string & import("effect/Brand").Brand<"SessionID">;
13
+ readonly time: number;
14
+ readonly direction: "previous" | "next";
19
15
  };
20
- readonly time: Schema.Finite;
21
- readonly direction: Schema.Literals<readonly ["previous", "next"]>;
22
- }>;
23
- }>, Schema.Struct<{
24
- readonly project: Schema.brand<Schema.String, "Project.ID"> & {
25
- global: string & import("effect/Brand").Brand<"Project.ID">;
26
- };
27
- readonly subpath: Schema.optional<Schema.brand<Schema.String, "RelativePath">>;
28
- readonly parentID: Schema.optional<Schema.Union<readonly [Schema.brand<Schema.String, "SessionID"> & {
29
- create: () => string & import("effect/Brand").Brand<"SessionID">;
30
- descending: (id?: string) => string & import("effect/Brand").Brand<"SessionID">;
31
- }, Schema.decodeTo<Schema.Null, Schema.Literal<"null">, never, never>]>>;
32
- readonly search: Schema.optional<Schema.String>;
33
- readonly order: Schema.optional<Schema.Union<readonly [Schema.Literal<"asc">, Schema.Literal<"desc">]>>;
34
- readonly anchor: Schema.Struct<{
35
- readonly id: Schema.brand<Schema.String, "SessionID"> & {
36
- create: () => string & import("effect/Brand").Brand<"SessionID">;
37
- descending: (id?: string) => string & import("effect/Brand").Brand<"SessionID">;
16
+ readonly parentID?: (string & import("effect/Brand").Brand<"SessionID">) | null | undefined;
17
+ readonly search?: string | undefined;
18
+ readonly order?: "asc" | "desc" | undefined;
19
+ } | {
20
+ readonly project: string & import("effect/Brand").Brand<"Project.ID">;
21
+ readonly anchor: {
22
+ readonly id: string & import("effect/Brand").Brand<"SessionID">;
23
+ readonly time: number;
24
+ readonly direction: "previous" | "next";
38
25
  };
39
- readonly time: Schema.Finite;
40
- readonly direction: Schema.Literals<readonly ["previous", "next"]>;
41
- }>;
42
- }>, Schema.Struct<{
43
- readonly parentID: Schema.optional<Schema.Union<readonly [Schema.brand<Schema.String, "SessionID"> & {
44
- create: () => string & import("effect/Brand").Brand<"SessionID">;
45
- descending: (id?: string) => string & import("effect/Brand").Brand<"SessionID">;
46
- }, Schema.decodeTo<Schema.Null, Schema.Literal<"null">, never, never>]>>;
47
- readonly search: Schema.optional<Schema.String>;
48
- readonly order: Schema.optional<Schema.Union<readonly [Schema.Literal<"asc">, Schema.Literal<"desc">]>>;
49
- readonly anchor: Schema.Struct<{
50
- readonly id: Schema.brand<Schema.String, "SessionID"> & {
51
- create: () => string & import("effect/Brand").Brand<"SessionID">;
52
- descending: (id?: string) => string & import("effect/Brand").Brand<"SessionID">;
26
+ readonly subpath?: (string & import("effect/Brand").Brand<"RelativePath">) | undefined;
27
+ readonly parentID?: (string & import("effect/Brand").Brand<"SessionID">) | null | undefined;
28
+ readonly search?: string | undefined;
29
+ readonly order?: "asc" | "desc" | undefined;
30
+ } | {
31
+ readonly anchor: {
32
+ readonly id: string & import("effect/Brand").Brand<"SessionID">;
33
+ readonly time: number;
34
+ readonly direction: "previous" | "next";
53
35
  };
54
- readonly time: Schema.Finite;
55
- readonly direction: Schema.Literals<readonly ["previous", "next"]>;
56
- }>;
57
- }>]>;
58
- export declare const SessionsCursor: Schema.brand<Schema.String, "SessionsCursor"> & {
59
- make: (input: typeof SessionsCursorInput.Type) => string & import("effect/Brand").Brand<"SessionsCursor">;
60
- parse: (input: string) => Effect.Effect<{
36
+ readonly parentID?: (string & import("effect/Brand").Brand<"SessionID">) | null | undefined;
37
+ readonly search?: string | undefined;
38
+ readonly order?: "asc" | "desc" | undefined;
39
+ }) => string & import("effect/Brand").Brand<"SessionsCursor">;
40
+ parse: (input: string) => import("effect/Effect").Effect<{
61
41
  readonly directory: string & import("effect/Brand").Brand<"AbsolutePath">;
62
42
  readonly anchor: {
63
43
  readonly id: string & import("effect/Brand").Brand<"SessionID">;
@@ -89,16 +69,41 @@ export declare const SessionsCursor: Schema.brand<Schema.String, "SessionsCursor
89
69
  readonly order?: "asc" | "desc" | undefined;
90
70
  }, "Invalid cursor", never>;
91
71
  };
92
- export type SessionsCursor = typeof SessionsCursor.Type;
72
+ export type SessionsCursor = Session.ListCursor;
93
73
  export declare const SessionsQuery: Schema.Struct<{
94
- readonly directory: Schema.optional<Schema.brand<Schema.String, "AbsolutePath">>;
95
- readonly project: Schema.optional<Schema.brand<Schema.String, "Project.ID"> & {
96
- global: string & import("effect/Brand").Brand<"Project.ID">;
97
- }>;
98
- readonly subpath: Schema.optional<Schema.brand<Schema.String, "RelativePath">>;
99
74
  readonly cursor: Schema.optional<Schema.brand<Schema.String, "SessionsCursor"> & {
100
- make: (input: typeof SessionsCursorInput.Type) => string & import("effect/Brand").Brand<"SessionsCursor">;
101
- parse: (input: string) => Effect.Effect<{
75
+ make: (input: {
76
+ readonly directory: string & import("effect/Brand").Brand<"AbsolutePath">;
77
+ readonly anchor: {
78
+ readonly id: string & import("effect/Brand").Brand<"SessionID">;
79
+ readonly time: number;
80
+ readonly direction: "previous" | "next";
81
+ };
82
+ readonly parentID?: (string & import("effect/Brand").Brand<"SessionID">) | null | undefined;
83
+ readonly search?: string | undefined;
84
+ readonly order?: "asc" | "desc" | undefined;
85
+ } | {
86
+ readonly project: string & import("effect/Brand").Brand<"Project.ID">;
87
+ readonly anchor: {
88
+ readonly id: string & import("effect/Brand").Brand<"SessionID">;
89
+ readonly time: number;
90
+ readonly direction: "previous" | "next";
91
+ };
92
+ readonly subpath?: (string & import("effect/Brand").Brand<"RelativePath">) | undefined;
93
+ readonly parentID?: (string & import("effect/Brand").Brand<"SessionID">) | null | undefined;
94
+ readonly search?: string | undefined;
95
+ readonly order?: "asc" | "desc" | undefined;
96
+ } | {
97
+ readonly anchor: {
98
+ readonly id: string & import("effect/Brand").Brand<"SessionID">;
99
+ readonly time: number;
100
+ readonly direction: "previous" | "next";
101
+ };
102
+ readonly parentID?: (string & import("effect/Brand").Brand<"SessionID">) | null | undefined;
103
+ readonly search?: string | undefined;
104
+ readonly order?: "asc" | "desc" | undefined;
105
+ }) => string & import("effect/Brand").Brand<"SessionsCursor">;
106
+ parse: (input: string) => import("effect/Effect").Effect<{
102
107
  readonly directory: string & import("effect/Brand").Brand<"AbsolutePath">;
103
108
  readonly anchor: {
104
109
  readonly id: string & import("effect/Brand").Brand<"SessionID">;
@@ -130,23 +135,53 @@ export declare const SessionsQuery: Schema.Struct<{
130
135
  readonly order?: "asc" | "desc" | undefined;
131
136
  }, "Invalid cursor", never>;
132
137
  }>;
133
- readonly limit: Schema.optional<Schema.compose<Schema.Int, Schema.NumberFromString>>;
134
- readonly order: Schema.optional<Schema.Union<readonly [Schema.Literal<"asc">, Schema.Literal<"desc">]>>;
138
+ readonly directory: Schema.optional<Schema.brand<Schema.String, "AbsolutePath">>;
139
+ readonly project: Schema.optional<Schema.brand<Schema.String, "Project.ID"> & {
140
+ global: string & import("effect/Brand").Brand<"Project.ID">;
141
+ }>;
142
+ readonly subpath: Schema.optional<Schema.brand<Schema.String, "RelativePath">>;
143
+ readonly order: Schema.optional<Schema.Literals<readonly ["asc", "desc"]>>;
135
144
  readonly search: Schema.optional<Schema.String>;
136
145
  readonly parentID: Schema.optional<Schema.Union<readonly [Schema.brand<Schema.String, "SessionID"> & {
137
146
  create: () => string & import("effect/Brand").Brand<"SessionID">;
138
147
  descending: (id?: string) => string & import("effect/Brand").Brand<"SessionID">;
139
148
  }, Schema.decodeTo<Schema.Null, Schema.Literal<"null">, never, never>]>>;
149
+ readonly limit: Schema.optional<Schema.compose<Schema.Int, Schema.NumberFromString>>;
140
150
  }>;
141
151
  export declare const makeSessionGroup: <I extends HttpApiMiddleware.AnyId, S, FormI extends HttpApiMiddleware.AnyId, FormS>(sessionLocationMiddleware: Context.Key<I, S>, formLocationMiddleware: Context.Key<FormI, FormS>) => HttpApiGroup.HttpApiGroup<"server.session", HttpApiEndpoint.HttpApiEndpoint<"session.list", "GET", "/api/session", never, Schema.toCodecStringTree<Schema.Struct<{
142
- readonly directory: Schema.optional<Schema.brand<Schema.String, "AbsolutePath">>;
143
- readonly project: Schema.optional<Schema.brand<Schema.String, "Project.ID"> & {
144
- global: string & import("effect/Brand").Brand<"Project.ID">;
145
- }>;
146
- readonly subpath: Schema.optional<Schema.brand<Schema.String, "RelativePath">>;
147
152
  readonly cursor: Schema.optional<Schema.brand<Schema.String, "SessionsCursor"> & {
148
- make: (input: typeof SessionsCursorInput.Type) => string & import("effect/Brand").Brand<"SessionsCursor">;
149
- parse: (input: string) => Effect.Effect<{
153
+ make: (input: {
154
+ readonly directory: string & import("effect/Brand").Brand<"AbsolutePath">;
155
+ readonly anchor: {
156
+ readonly id: string & import("effect/Brand").Brand<"SessionID">;
157
+ readonly time: number;
158
+ readonly direction: "previous" | "next";
159
+ };
160
+ readonly parentID?: (string & import("effect/Brand").Brand<"SessionID">) | null | undefined;
161
+ readonly search?: string | undefined;
162
+ readonly order?: "asc" | "desc" | undefined;
163
+ } | {
164
+ readonly project: string & import("effect/Brand").Brand<"Project.ID">;
165
+ readonly anchor: {
166
+ readonly id: string & import("effect/Brand").Brand<"SessionID">;
167
+ readonly time: number;
168
+ readonly direction: "previous" | "next";
169
+ };
170
+ readonly subpath?: (string & import("effect/Brand").Brand<"RelativePath">) | undefined;
171
+ readonly parentID?: (string & import("effect/Brand").Brand<"SessionID">) | null | undefined;
172
+ readonly search?: string | undefined;
173
+ readonly order?: "asc" | "desc" | undefined;
174
+ } | {
175
+ readonly anchor: {
176
+ readonly id: string & import("effect/Brand").Brand<"SessionID">;
177
+ readonly time: number;
178
+ readonly direction: "previous" | "next";
179
+ };
180
+ readonly parentID?: (string & import("effect/Brand").Brand<"SessionID">) | null | undefined;
181
+ readonly search?: string | undefined;
182
+ readonly order?: "asc" | "desc" | undefined;
183
+ }) => string & import("effect/Brand").Brand<"SessionsCursor">;
184
+ parse: (input: string) => import("effect/Effect").Effect<{
150
185
  readonly directory: string & import("effect/Brand").Brand<"AbsolutePath">;
151
186
  readonly anchor: {
152
187
  readonly id: string & import("effect/Brand").Brand<"SessionID">;
@@ -178,13 +213,18 @@ export declare const makeSessionGroup: <I extends HttpApiMiddleware.AnyId, S, Fo
178
213
  readonly order?: "asc" | "desc" | undefined;
179
214
  }, "Invalid cursor", never>;
180
215
  }>;
181
- readonly limit: Schema.optional<Schema.compose<Schema.Int, Schema.NumberFromString>>;
182
- readonly order: Schema.optional<Schema.Union<readonly [Schema.Literal<"asc">, Schema.Literal<"desc">]>>;
216
+ readonly directory: Schema.optional<Schema.brand<Schema.String, "AbsolutePath">>;
217
+ readonly project: Schema.optional<Schema.brand<Schema.String, "Project.ID"> & {
218
+ global: string & import("effect/Brand").Brand<"Project.ID">;
219
+ }>;
220
+ readonly subpath: Schema.optional<Schema.brand<Schema.String, "RelativePath">>;
221
+ readonly order: Schema.optional<Schema.Literals<readonly ["asc", "desc"]>>;
183
222
  readonly search: Schema.optional<Schema.String>;
184
223
  readonly parentID: Schema.optional<Schema.Union<readonly [Schema.brand<Schema.String, "SessionID"> & {
185
224
  create: () => string & import("effect/Brand").Brand<"SessionID">;
186
225
  descending: (id?: string) => string & import("effect/Brand").Brand<"SessionID">;
187
226
  }, Schema.decodeTo<Schema.Null, Schema.Literal<"null">, never, never>]>>;
227
+ readonly limit: Schema.optional<Schema.compose<Schema.Int, Schema.NumberFromString>>;
188
228
  }>>, never, never, Schema.toCodecJson<Schema.Struct<{
189
229
  readonly data: Schema.$Array<Schema.Struct<{
190
230
  readonly location: Schema.Struct<{
@@ -363,8 +403,38 @@ export declare const makeSessionGroup: <I extends HttpApiMiddleware.AnyId, S, Fo
363
403
  }>>;
364
404
  readonly cursor: Schema.Struct<{
365
405
  readonly previous: Schema.optional<Schema.brand<Schema.String, "SessionsCursor"> & {
366
- make: (input: typeof SessionsCursorInput.Type) => string & import("effect/Brand").Brand<"SessionsCursor">;
367
- parse: (input: string) => Effect.Effect<{
406
+ make: (input: {
407
+ readonly directory: string & import("effect/Brand").Brand<"AbsolutePath">;
408
+ readonly anchor: {
409
+ readonly id: string & import("effect/Brand").Brand<"SessionID">;
410
+ readonly time: number;
411
+ readonly direction: "previous" | "next";
412
+ };
413
+ readonly parentID?: (string & import("effect/Brand").Brand<"SessionID">) | null | undefined;
414
+ readonly search?: string | undefined;
415
+ readonly order?: "asc" | "desc" | undefined;
416
+ } | {
417
+ readonly project: string & import("effect/Brand").Brand<"Project.ID">;
418
+ readonly anchor: {
419
+ readonly id: string & import("effect/Brand").Brand<"SessionID">;
420
+ readonly time: number;
421
+ readonly direction: "previous" | "next";
422
+ };
423
+ readonly subpath?: (string & import("effect/Brand").Brand<"RelativePath">) | undefined;
424
+ readonly parentID?: (string & import("effect/Brand").Brand<"SessionID">) | null | undefined;
425
+ readonly search?: string | undefined;
426
+ readonly order?: "asc" | "desc" | undefined;
427
+ } | {
428
+ readonly anchor: {
429
+ readonly id: string & import("effect/Brand").Brand<"SessionID">;
430
+ readonly time: number;
431
+ readonly direction: "previous" | "next";
432
+ };
433
+ readonly parentID?: (string & import("effect/Brand").Brand<"SessionID">) | null | undefined;
434
+ readonly search?: string | undefined;
435
+ readonly order?: "asc" | "desc" | undefined;
436
+ }) => string & import("effect/Brand").Brand<"SessionsCursor">;
437
+ parse: (input: string) => import("effect/Effect").Effect<{
368
438
  readonly directory: string & import("effect/Brand").Brand<"AbsolutePath">;
369
439
  readonly anchor: {
370
440
  readonly id: string & import("effect/Brand").Brand<"SessionID">;
@@ -397,8 +467,38 @@ export declare const makeSessionGroup: <I extends HttpApiMiddleware.AnyId, S, Fo
397
467
  }, "Invalid cursor", never>;
398
468
  }>;
399
469
  readonly next: Schema.optional<Schema.brand<Schema.String, "SessionsCursor"> & {
400
- make: (input: typeof SessionsCursorInput.Type) => string & import("effect/Brand").Brand<"SessionsCursor">;
401
- parse: (input: string) => Effect.Effect<{
470
+ make: (input: {
471
+ readonly directory: string & import("effect/Brand").Brand<"AbsolutePath">;
472
+ readonly anchor: {
473
+ readonly id: string & import("effect/Brand").Brand<"SessionID">;
474
+ readonly time: number;
475
+ readonly direction: "previous" | "next";
476
+ };
477
+ readonly parentID?: (string & import("effect/Brand").Brand<"SessionID">) | null | undefined;
478
+ readonly search?: string | undefined;
479
+ readonly order?: "asc" | "desc" | undefined;
480
+ } | {
481
+ readonly project: string & import("effect/Brand").Brand<"Project.ID">;
482
+ readonly anchor: {
483
+ readonly id: string & import("effect/Brand").Brand<"SessionID">;
484
+ readonly time: number;
485
+ readonly direction: "previous" | "next";
486
+ };
487
+ readonly subpath?: (string & import("effect/Brand").Brand<"RelativePath">) | undefined;
488
+ readonly parentID?: (string & import("effect/Brand").Brand<"SessionID">) | null | undefined;
489
+ readonly search?: string | undefined;
490
+ readonly order?: "asc" | "desc" | undefined;
491
+ } | {
492
+ readonly anchor: {
493
+ readonly id: string & import("effect/Brand").Brand<"SessionID">;
494
+ readonly time: number;
495
+ readonly direction: "previous" | "next";
496
+ };
497
+ readonly parentID?: (string & import("effect/Brand").Brand<"SessionID">) | null | undefined;
498
+ readonly search?: string | undefined;
499
+ readonly order?: "asc" | "desc" | undefined;
500
+ }) => string & import("effect/Brand").Brand<"SessionsCursor">;
501
+ parse: (input: string) => import("effect/Effect").Effect<{
402
502
  readonly directory: string & import("effect/Brand").Brand<"AbsolutePath">;
403
503
  readonly anchor: {
404
504
  readonly id: string & import("effect/Brand").Brand<"SessionID">;
@@ -11600,4 +11700,3 @@ export declare const makeSessionGroup: <I extends HttpApiMiddleware.AnyId, S, Fo
11600
11700
  }>>, never, Schema.toCodecJson<Schema.Struct<{
11601
11701
  readonly idle: Schema.decodeTo<Schema.DateTimeUtc, Schema.Finite, never, never>;
11602
11702
  }>>, never, Schema.toCodecJson<HttpApiSchema.NoContent>, Schema.toCodecJson<typeof SessionNotFoundError>, never, never>, false>;
11603
- export {};
@@ -5,10 +5,9 @@ import { Session } from "@opencode/schema/session";
5
5
  import { SessionStats } from "@opencode/schema/session-stats";
6
6
  import { InstructionEntry } from "@opencode/schema/instruction-entry";
7
7
  import { Project } from "@opencode/schema/project";
8
- import { AbsolutePath, DateTimeUtcFromMillis, NonNegativeInt, PositiveInt, RelativePath, statics, } from "@opencode/schema/schema";
8
+ import { DateTimeUtcFromMillis, NonNegativeInt, PositiveInt } from "@opencode/schema/schema";
9
9
  import { Event } from "@opencode/schema/event";
10
- import { Context, Effect, Result, Schema, SchemaGetter, SchemaParser, Struct } from "effect";
11
- import { Base64Url } from "effect/encoding";
10
+ import { Context, Schema, SchemaGetter, Struct } from "effect";
12
11
  import { HttpApiEndpoint, HttpApiGroup, HttpApiMiddleware, HttpApiSchema, OpenApi } from "effect/http-api";
13
12
  import { ConflictError, LocationNotFoundError, CommandExecutionError, CommandNotFoundError, FormAlreadySettledError, FormInvalidAnswerError, FormNotFoundError, InvalidCursorError, InvalidRequestError, MessageNotFoundError, ServiceUnavailableError, SessionBusyError, SessionNotFoundError, SkillNotFoundError, UnknownError, } from "../errors.js";
14
13
  import { Agent } from "@opencode/schema/agent";
@@ -21,64 +20,6 @@ import { EventLog } from "@opencode/schema/event-log";
21
20
  import { FileDiff } from "@opencode/schema/file-diff";
22
21
  import { Form } from "@opencode/schema/form";
23
22
  import { PublicSessionMessage } from "./message.js";
24
- const ParentIDFilter = Schema.Union([
25
- Session.ID,
26
- Schema.Null.pipe(Schema.encodeTo(Schema.Literal("null"), {
27
- decode: SchemaGetter.transform(() => null),
28
- encode: SchemaGetter.transform(() => "null"),
29
- })),
30
- ]).annotate({
31
- description: "Filter by parent session. Use null to return only root sessions.",
32
- });
33
- const SessionsQueryFields = {
34
- limit: Schema.NumberFromString.pipe(Schema.decodeTo(PositiveInt), Schema.optional).annotate({
35
- description: "Maximum number of sessions to return. Defaults to the newest 50 sessions.",
36
- }),
37
- order: Schema.optional(Schema.Union([Schema.Literal("asc"), Schema.Literal("desc")])).annotate({
38
- description: "Session order for the first page. Use desc for newest first or asc for oldest first.",
39
- }),
40
- search: Schema.optional(Schema.String),
41
- parentID: ParentIDFilter.pipe(Schema.optional),
42
- };
43
- const SessionsDirectoryQuery = Schema.Struct({
44
- ...SessionsQueryFields,
45
- directory: AbsolutePath,
46
- });
47
- const SessionsProjectQuery = Schema.Struct({
48
- ...SessionsQueryFields,
49
- project: Project.ID,
50
- subpath: RelativePath.pipe(Schema.optional),
51
- });
52
- const SessionsAllQuery = Schema.Struct(SessionsQueryFields);
53
- const withCursor = (schema) => schema.mapFields((fields) => ({
54
- ...Struct.omit(fields, ["limit"]),
55
- anchor: Session.ListAnchor,
56
- }));
57
- const SessionsCursorInput = Schema.Union([
58
- withCursor(SessionsDirectoryQuery),
59
- withCursor(SessionsProjectQuery),
60
- withCursor(SessionsAllQuery),
61
- ]);
62
- const SessionsCursorJson = Schema.fromJsonString(SessionsCursorInput);
63
- const encodeSessionsCursor = Schema.encodeSync(SessionsCursorJson);
64
- const decodeSessionsCursor = Schema.decodeUnknownEffect(SessionsCursorJson);
65
- const invalidCursor = "Invalid cursor";
66
- export const SessionsCursor = Schema.String.pipe(Schema.brand("SessionsCursor"), Schema.annotate({
67
- identifier: "SessionsCursor",
68
- description: "Opaque pagination cursor returned as cursor.previous or cursor.next in the previous response.",
69
- }), statics((schema) => {
70
- // Read the default constructor without caching it on the schema, so `make` can be replaced.
71
- const make = SchemaParser.make(schema);
72
- return {
73
- make: (input) => make(Base64Url.encode(encodeSessionsCursor(input))),
74
- parse: (input) => Effect.suspend(() => {
75
- const result = Base64Url.decodeString(input);
76
- return Result.isFailure(result)
77
- ? Effect.fail(invalidCursor)
78
- : decodeSessionsCursor(result.success).pipe(Effect.mapError(() => invalidCursor));
79
- }),
80
- };
81
- }));
82
23
  const SessionActive = Schema.Struct({
83
24
  type: Schema.Literal("running"),
84
25
  }).annotate({ identifier: "SessionActive" });
@@ -114,12 +55,14 @@ const BooleanFromString = Schema.Literals(["true", "false"]).pipe(Schema.decodeT
114
55
  decode: SchemaGetter.transform((value) => value === "true"),
115
56
  encode: SchemaGetter.transform((value) => (value ? "true" : "false")),
116
57
  }));
58
+ // Kept so existing imports of SessionsCursor from Protocol keep working.
59
+ export const SessionsCursor = Session.ListCursor;
117
60
  export const SessionsQuery = Schema.Struct({
118
- ...SessionsQueryFields,
119
- directory: AbsolutePath.pipe(Schema.optional),
120
- project: Project.ID.pipe(Schema.optional),
121
- subpath: RelativePath.pipe(Schema.optional),
122
- cursor: SessionsCursor.pipe(Schema.optional),
61
+ limit: Schema.NumberFromString.pipe(Schema.decodeTo(PositiveInt), Schema.optional).annotate({
62
+ description: "Maximum number of sessions to return. Defaults to the newest 50 sessions.",
63
+ }),
64
+ ...Session.ListFilter.fields,
65
+ cursor: Session.ListCursor.pipe(Schema.optional),
123
66
  }).annotate({ identifier: "SessionsQuery" });
124
67
  export const makeSessionGroup = (sessionLocationMiddleware, formLocationMiddleware) => HttpApiGroup.make("server.session")
125
68
  .add(HttpApiEndpoint.get("session.list", "/api/session", {
@@ -127,8 +70,8 @@ export const makeSessionGroup = (sessionLocationMiddleware, formLocationMiddlewa
127
70
  success: Schema.Struct({
128
71
  data: Schema.Array(PublicSessionInfo),
129
72
  cursor: Schema.Struct({
130
- previous: SessionsCursor.pipe(Schema.optional),
131
- next: SessionsCursor.pipe(Schema.optional),
73
+ previous: Session.ListCursor.pipe(Schema.optional),
74
+ next: Session.ListCursor.pipe(Schema.optional),
132
75
  }),
133
76
  }).annotate({ identifier: "SessionsResponse" }),
134
77
  error: [InvalidCursorError, InvalidRequestError],
@@ -0,0 +1,60 @@
1
+ import { Schema } from "effect";
2
+ import { HttpApiEndpoint, HttpApiGroup } from "effect/http-api";
3
+ import { InvalidRequestError, LocationNotFoundError, ServiceUnavailableError } from "../errors.js";
4
+ export declare const VoiceWebRTCTransportInput: Schema.Struct<{
5
+ readonly type: Schema.Literal<"webrtc">;
6
+ readonly sdp: Schema.String;
7
+ readonly dcid: Schema.optional<Schema.Number>;
8
+ }>;
9
+ export declare const VoiceWebSocketTransportInput: Schema.Struct<{
10
+ readonly type: Schema.Literal<"websocket">;
11
+ }>;
12
+ export declare const VoiceTransportInput: Schema.Union<readonly [Schema.Struct<{
13
+ readonly type: Schema.Literal<"webrtc">;
14
+ readonly sdp: Schema.String;
15
+ readonly dcid: Schema.optional<Schema.Number>;
16
+ }>, Schema.Struct<{
17
+ readonly type: Schema.Literal<"websocket">;
18
+ }>]>;
19
+ export declare const VoiceWebRTCTransport: Schema.Struct<{
20
+ readonly type: Schema.Literal<"webrtc">;
21
+ readonly sdp: Schema.String;
22
+ }>;
23
+ export declare const VoiceWebSocketTransport: Schema.Struct<{
24
+ readonly type: Schema.Literal<"websocket">;
25
+ readonly url: Schema.String;
26
+ readonly token: Schema.String;
27
+ readonly expiresAt: Schema.Number;
28
+ }>;
29
+ export declare const VoiceTransport: Schema.Union<readonly [Schema.Struct<{
30
+ readonly type: Schema.Literal<"webrtc">;
31
+ readonly sdp: Schema.String;
32
+ }>, Schema.Struct<{
33
+ readonly type: Schema.Literal<"websocket">;
34
+ readonly url: Schema.String;
35
+ readonly token: Schema.String;
36
+ readonly expiresAt: Schema.Number;
37
+ }>]>;
38
+ export declare const VoiceGroup: HttpApiGroup.HttpApiGroup<"server.voice", HttpApiEndpoint.HttpApiEndpoint<"voice.session", "POST", "/api/experimental/voice/session", never, never, Schema.toCodecJson<Schema.Struct<{
39
+ readonly model: Schema.String;
40
+ readonly session: Schema.optional<Schema.$Record<Schema.String, Schema.Unknown>>;
41
+ readonly transport: Schema.Union<readonly [Schema.Struct<{
42
+ readonly type: Schema.Literal<"webrtc">;
43
+ readonly sdp: Schema.String;
44
+ readonly dcid: Schema.optional<Schema.Number>;
45
+ }>, Schema.Struct<{
46
+ readonly type: Schema.Literal<"websocket">;
47
+ }>]>;
48
+ }>>, never, Schema.toCodecJson<Schema.Struct<{
49
+ readonly data: Schema.Struct<{
50
+ readonly transport: Schema.Union<readonly [Schema.Struct<{
51
+ readonly type: Schema.Literal<"webrtc">;
52
+ readonly sdp: Schema.String;
53
+ }>, Schema.Struct<{
54
+ readonly type: Schema.Literal<"websocket">;
55
+ readonly url: Schema.String;
56
+ readonly token: Schema.String;
57
+ readonly expiresAt: Schema.Number;
58
+ }>]>;
59
+ }>;
60
+ }>>, Schema.toCodecJson<typeof LocationNotFoundError | typeof InvalidRequestError | typeof ServiceUnavailableError>, never, never>, false>;
@@ -0,0 +1,51 @@
1
+ import { Schema } from "effect";
2
+ import { HttpApiEndpoint, HttpApiGroup, OpenApi } from "effect/http-api";
3
+ import { InvalidRequestError, LocationNotFoundError, ServiceUnavailableError } from "../errors.js";
4
+ export const VoiceWebRTCTransportInput = Schema.Struct({
5
+ type: Schema.Literal("webrtc"),
6
+ sdp: Schema.String,
7
+ dcid: Schema.optional(Schema.Number),
8
+ }).annotate({ identifier: "VoiceWebRTCTransportInput" });
9
+ export const VoiceWebSocketTransportInput = Schema.Struct({
10
+ type: Schema.Literal("websocket"),
11
+ }).annotate({ identifier: "VoiceWebSocketTransportInput" });
12
+ export const VoiceTransportInput = Schema.Union([
13
+ VoiceWebRTCTransportInput,
14
+ VoiceWebSocketTransportInput,
15
+ ]).annotate({ identifier: "VoiceTransportInput" });
16
+ export const VoiceWebRTCTransport = Schema.Struct({
17
+ type: Schema.Literal("webrtc"),
18
+ sdp: Schema.String,
19
+ }).annotate({ identifier: "VoiceWebRTCTransport" });
20
+ export const VoiceWebSocketTransport = Schema.Struct({
21
+ type: Schema.Literal("websocket"),
22
+ url: Schema.String,
23
+ token: Schema.String,
24
+ expiresAt: Schema.Number,
25
+ }).annotate({ identifier: "VoiceWebSocketTransport" });
26
+ export const VoiceTransport = Schema.Union([
27
+ VoiceWebRTCTransport,
28
+ VoiceWebSocketTransport,
29
+ ]).annotate({ identifier: "VoiceTransport" });
30
+ export const VoiceGroup = HttpApiGroup.make("server.voice")
31
+ .add(HttpApiEndpoint.post("voice.session", "/api/experimental/voice/session", {
32
+ payload: Schema.Struct({
33
+ model: Schema.String,
34
+ session: Schema.optional(Schema.Record(Schema.String, Schema.Unknown)),
35
+ transport: VoiceTransportInput,
36
+ }),
37
+ success: Schema.Struct({
38
+ data: Schema.Struct({
39
+ transport: VoiceTransport,
40
+ }),
41
+ }).annotate({ identifier: "VoiceSessionResponse" }),
42
+ error: [InvalidRequestError, ServiceUnavailableError, LocationNotFoundError],
43
+ }).annotateMerge(OpenApi.annotations({
44
+ identifier: "experimental.voice.session",
45
+ summary: "Create voice session",
46
+ description: "Create a server-brokered voice session using the server's configured provider credentials and return the WebRTC SDP answer or WebSocket ephemeral token.",
47
+ })))
48
+ .annotateMerge(OpenApi.annotations({
49
+ title: "voice",
50
+ description: "Experimental server-brokered voice session routes.",
51
+ }));
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/package.json",
3
3
  "name": "@opencode/protocol",
4
- "version": "0.0.0-dev-21085",
4
+ "version": "0.0.0-dev-21090",
5
5
  "type": "module",
6
6
  "license": "MIT",
7
7
  "repository": {
@@ -33,7 +33,7 @@
33
33
  "typecheck": "tsgo --noEmit"
34
34
  },
35
35
  "dependencies": {
36
- "@opencode/schema": "0.0.0-dev-21085",
36
+ "@opencode/schema": "0.0.0-dev-21090",
37
37
  "effect": "4.0.1"
38
38
  },
39
39
  "devDependencies": {