@kilocode/protocol 0.0.0-stage → 0.0.0-v2-9

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.
Files changed (76) hide show
  1. package/dist/api.d.ts +58 -0
  2. package/dist/api.js +77 -0
  3. package/dist/client.d.ts +63 -0
  4. package/dist/client.js +55 -0
  5. package/dist/errors.d.ts +193 -0
  6. package/dist/errors.js +152 -0
  7. package/dist/groups/agent.d.ts +225 -0
  8. package/dist/groups/agent.js +30 -0
  9. package/dist/groups/command.d.ts +15 -0
  10. package/dist/groups/command.js +20 -0
  11. package/dist/groups/config.d.ts +14 -0
  12. package/dist/groups/config.js +32 -0
  13. package/dist/groups/credential.d.ts +93 -0
  14. package/dist/groups/credential.js +50 -0
  15. package/dist/groups/debug.d.ts +22 -0
  16. package/dist/groups/debug.js +49 -0
  17. package/dist/groups/event.d.ts +14853 -0
  18. package/dist/groups/event.js +51 -0
  19. package/dist/groups/form.d.ts +138 -0
  20. package/dist/groups/form.js +18 -0
  21. package/dist/groups/fs.d.ts +48 -0
  22. package/dist/groups/fs.js +73 -0
  23. package/dist/groups/generate.d.ts +33 -0
  24. package/dist/groups/generate.js +23 -0
  25. package/dist/groups/integration.d.ts +1724 -0
  26. package/dist/groups/integration.js +169 -0
  27. package/dist/groups/location.d.ts +23 -0
  28. package/dist/groups/location.js +45 -0
  29. package/dist/groups/mcp.d.ts +103 -0
  30. package/dist/groups/mcp.js +114 -0
  31. package/dist/groups/message.d.ts +1416 -0
  32. package/dist/groups/message.js +77 -0
  33. package/dist/groups/migration.d.ts +28 -0
  34. package/dist/groups/migration.js +21 -0
  35. package/dist/groups/model.d.ts +399 -0
  36. package/dist/groups/model.js +33 -0
  37. package/dist/groups/permission.d.ts +175 -0
  38. package/dist/groups/permission.js +110 -0
  39. package/dist/groups/persistent-pty.d.ts +242 -0
  40. package/dist/groups/persistent-pty.js +92 -0
  41. package/dist/groups/plugin.d.ts +86 -0
  42. package/dist/groups/plugin.js +45 -0
  43. package/dist/groups/project.d.ts +83 -0
  44. package/dist/groups/project.js +33 -0
  45. package/dist/groups/provider.d.ts +231 -0
  46. package/dist/groups/provider.js +34 -0
  47. package/dist/groups/pty.d.ts +151 -0
  48. package/dist/groups/pty.js +112 -0
  49. package/dist/groups/reference.d.ts +25 -0
  50. package/dist/groups/reference.js +33 -0
  51. package/dist/groups/rpc.d.ts +21 -0
  52. package/dist/groups/rpc.js +24 -0
  53. package/dist/groups/server.d.ts +44 -0
  54. package/dist/groups/server.js +53 -0
  55. package/dist/groups/session.d.ts +11380 -0
  56. package/dist/groups/session.js +611 -0
  57. package/dist/groups/shell.d.ts +125 -0
  58. package/dist/groups/shell.js +64 -0
  59. package/dist/groups/skill.d.ts +19 -0
  60. package/dist/groups/skill.js +20 -0
  61. package/dist/groups/vcs.d.ts +87 -0
  62. package/dist/groups/vcs.js +93 -0
  63. package/dist/groups/voice.d.ts +93 -0
  64. package/dist/groups/voice.js +89 -0
  65. package/dist/groups/websearch.d.ts +29 -0
  66. package/dist/groups/websearch.js +34 -0
  67. package/dist/groups/worktree.d.ts +41 -0
  68. package/dist/groups/worktree.js +52 -0
  69. package/dist/middleware/authorization.d.ts +13 -0
  70. package/dist/middleware/authorization.js +6 -0
  71. package/dist/middleware/schema-error.d.ts +13 -0
  72. package/dist/middleware/schema-error.js +4 -0
  73. package/dist/simulation.d.ts +1830 -0
  74. package/dist/simulation.js +497 -0
  75. package/package.json +45 -4
  76. package/README.md +0 -3
@@ -0,0 +1,151 @@
1
+ import { Context, Schema } from "effect";
2
+ import { HttpApiEndpoint, HttpApiGroup, HttpApiMiddleware, HttpApiSchema } from "effect/http-api";
3
+ import { ForbiddenError, LocationNotFoundError, PtyNotFoundError } from "../errors.js";
4
+ export declare const PTY_CONNECT_TICKET_QUERY = "ticket";
5
+ export declare const PTY_CONNECT_TOKEN_HEADER = "x-opencode-ticket";
6
+ export declare const PTY_CONNECT_TOKEN_HEADER_VALUE = "1";
7
+ export declare const PTY_CONNECT_PATH = "/api/pty/:ptyID/connect";
8
+ export declare function hasPtyConnectTicketURL(url: URL): boolean;
9
+ export declare const makePtyGroup: <LocationId extends HttpApiMiddleware.AnyId, LocationService>(locationMiddleware: Context.Key<LocationId, LocationService>) => HttpApiGroup.HttpApiGroup<"server.pty", HttpApiEndpoint.HttpApiEndpoint<"pty.create", "POST", "/api/pty", never, Schema.toCodecStringTree<Schema.Struct<{
10
+ readonly location: Schema.optional<Schema.Struct<{
11
+ readonly directory: Schema.optional<Schema.String>;
12
+ }>>;
13
+ }>>, Schema.toCodecJson<Schema.Struct<{
14
+ readonly command: Schema.decodeTo<Schema.optional<Schema.toType<Schema.String>>, Schema.optionalKey<Schema.String>, never, never>;
15
+ readonly args: Schema.decodeTo<Schema.optional<Schema.toType<Schema.$Array<Schema.String>>>, Schema.optionalKey<Schema.$Array<Schema.String>>, never, never>;
16
+ readonly cwd: Schema.decodeTo<Schema.optional<Schema.toType<Schema.String>>, Schema.optionalKey<Schema.String>, never, never>;
17
+ readonly title: Schema.decodeTo<Schema.optional<Schema.toType<Schema.String>>, Schema.optionalKey<Schema.String>, never, never>;
18
+ readonly env: Schema.decodeTo<Schema.optional<Schema.toType<Schema.$Record<Schema.String, Schema.String>>>, Schema.optionalKey<Schema.$Record<Schema.String, Schema.String>>, never, never>;
19
+ }>>, never, Schema.toCodecJson<Schema.Struct<{
20
+ readonly location: Schema.Struct<{
21
+ readonly directory: Schema.brand<Schema.String, "AbsolutePath">;
22
+ }>;
23
+ readonly data: Schema.Struct<{
24
+ readonly id: Schema.brand<Schema.String, "PtyID"> & {
25
+ create: () => string & import("effect/Brand").Brand<"PtyID">;
26
+ ascending: (id?: string) => string & import("effect/Brand").Brand<"PtyID">;
27
+ };
28
+ readonly title: Schema.String;
29
+ readonly command: Schema.String;
30
+ readonly args: Schema.$Array<Schema.String>;
31
+ readonly cwd: Schema.String;
32
+ readonly status: Schema.Literals<readonly ["running", "exited"]>;
33
+ readonly pid: Schema.Int;
34
+ readonly exitCode: Schema.decodeTo<Schema.optional<Schema.toType<Schema.Int>>, Schema.optionalKey<Schema.Int>, never, never>;
35
+ }>;
36
+ }>>, never, LocationId, HttpApiMiddleware.Requires<LocationId>> | HttpApiEndpoint.HttpApiEndpoint<"pty.list", "GET", "/api/pty", never, Schema.toCodecStringTree<Schema.Struct<{
37
+ readonly location: Schema.optional<Schema.Struct<{
38
+ readonly directory: Schema.optional<Schema.String>;
39
+ }>>;
40
+ }>>, never, never, Schema.toCodecJson<Schema.Struct<{
41
+ readonly location: Schema.Struct<{
42
+ readonly directory: Schema.brand<Schema.String, "AbsolutePath">;
43
+ }>;
44
+ readonly data: Schema.$Array<Schema.Struct<{
45
+ readonly id: Schema.brand<Schema.String, "PtyID"> & {
46
+ create: () => string & import("effect/Brand").Brand<"PtyID">;
47
+ ascending: (id?: string) => string & import("effect/Brand").Brand<"PtyID">;
48
+ };
49
+ readonly title: Schema.String;
50
+ readonly command: Schema.String;
51
+ readonly args: Schema.$Array<Schema.String>;
52
+ readonly cwd: Schema.String;
53
+ readonly status: Schema.Literals<readonly ["running", "exited"]>;
54
+ readonly pid: Schema.Int;
55
+ readonly exitCode: Schema.decodeTo<Schema.optional<Schema.toType<Schema.Int>>, Schema.optionalKey<Schema.Int>, never, never>;
56
+ }>>;
57
+ }>>, never, LocationId, HttpApiMiddleware.Requires<LocationId>> | HttpApiEndpoint.HttpApiEndpoint<"pty.get", "GET", "/api/pty/:ptyID", Schema.toCodecStringTree<Schema.Struct<{
58
+ ptyID: Schema.brand<Schema.String, "PtyID"> & {
59
+ create: () => string & import("effect/Brand").Brand<"PtyID">;
60
+ ascending: (id?: string) => string & import("effect/Brand").Brand<"PtyID">;
61
+ };
62
+ }>>, Schema.toCodecStringTree<Schema.Struct<{
63
+ readonly location: Schema.optional<Schema.Struct<{
64
+ readonly directory: Schema.optional<Schema.String>;
65
+ }>>;
66
+ }>>, never, never, Schema.toCodecJson<Schema.Struct<{
67
+ readonly location: Schema.Struct<{
68
+ readonly directory: Schema.brand<Schema.String, "AbsolutePath">;
69
+ }>;
70
+ readonly data: Schema.Struct<{
71
+ readonly id: Schema.brand<Schema.String, "PtyID"> & {
72
+ create: () => string & import("effect/Brand").Brand<"PtyID">;
73
+ ascending: (id?: string) => string & import("effect/Brand").Brand<"PtyID">;
74
+ };
75
+ readonly title: Schema.String;
76
+ readonly command: Schema.String;
77
+ readonly args: Schema.$Array<Schema.String>;
78
+ readonly cwd: Schema.String;
79
+ readonly status: Schema.Literals<readonly ["running", "exited"]>;
80
+ readonly pid: Schema.Int;
81
+ readonly exitCode: Schema.decodeTo<Schema.optional<Schema.toType<Schema.Int>>, Schema.optionalKey<Schema.Int>, never, never>;
82
+ }>;
83
+ }>>, Schema.toCodecJson<typeof PtyNotFoundError>, LocationId, HttpApiMiddleware.Requires<LocationId>> | HttpApiEndpoint.HttpApiEndpoint<"pty.remove", "DELETE", "/api/pty/:ptyID", Schema.toCodecStringTree<Schema.Struct<{
84
+ ptyID: Schema.brand<Schema.String, "PtyID"> & {
85
+ create: () => string & import("effect/Brand").Brand<"PtyID">;
86
+ ascending: (id?: string) => string & import("effect/Brand").Brand<"PtyID">;
87
+ };
88
+ }>>, Schema.toCodecStringTree<Schema.Struct<{
89
+ readonly location: Schema.optional<Schema.Struct<{
90
+ readonly directory: Schema.optional<Schema.String>;
91
+ }>>;
92
+ }>>, never, never, Schema.toCodecJson<HttpApiSchema.NoContent>, Schema.toCodecJson<typeof PtyNotFoundError>, LocationId, HttpApiMiddleware.Requires<LocationId>> | HttpApiEndpoint.HttpApiEndpoint<"pty.update", "PUT", "/api/pty/:ptyID", Schema.toCodecStringTree<Schema.Struct<{
93
+ ptyID: Schema.brand<Schema.String, "PtyID"> & {
94
+ create: () => string & import("effect/Brand").Brand<"PtyID">;
95
+ ascending: (id?: string) => string & import("effect/Brand").Brand<"PtyID">;
96
+ };
97
+ }>>, Schema.toCodecStringTree<Schema.Struct<{
98
+ readonly location: Schema.optional<Schema.Struct<{
99
+ readonly directory: Schema.optional<Schema.String>;
100
+ }>>;
101
+ }>>, Schema.toCodecJson<Schema.Struct<{
102
+ readonly title: Schema.decodeTo<Schema.optional<Schema.toType<Schema.String>>, Schema.optionalKey<Schema.String>, never, never>;
103
+ readonly size: Schema.decodeTo<Schema.optional<Schema.toType<Schema.Struct<{
104
+ readonly rows: Schema.Int;
105
+ readonly cols: Schema.Int;
106
+ }>>>, Schema.optionalKey<Schema.Struct<{
107
+ readonly rows: Schema.Int;
108
+ readonly cols: Schema.Int;
109
+ }>>, never, never>;
110
+ }>>, never, Schema.toCodecJson<Schema.Struct<{
111
+ readonly location: Schema.Struct<{
112
+ readonly directory: Schema.brand<Schema.String, "AbsolutePath">;
113
+ }>;
114
+ readonly data: Schema.Struct<{
115
+ readonly id: Schema.brand<Schema.String, "PtyID"> & {
116
+ create: () => string & import("effect/Brand").Brand<"PtyID">;
117
+ ascending: (id?: string) => string & import("effect/Brand").Brand<"PtyID">;
118
+ };
119
+ readonly title: Schema.String;
120
+ readonly command: Schema.String;
121
+ readonly args: Schema.$Array<Schema.String>;
122
+ readonly cwd: Schema.String;
123
+ readonly status: Schema.Literals<readonly ["running", "exited"]>;
124
+ readonly pid: Schema.Int;
125
+ readonly exitCode: Schema.decodeTo<Schema.optional<Schema.toType<Schema.Int>>, Schema.optionalKey<Schema.Int>, never, never>;
126
+ }>;
127
+ }>>, Schema.toCodecJson<typeof PtyNotFoundError>, LocationId, HttpApiMiddleware.Requires<LocationId>> | HttpApiEndpoint.HttpApiEndpoint<"pty.connectToken", "POST", "/api/pty/:ptyID/connect-token", Schema.toCodecStringTree<Schema.Struct<{
128
+ ptyID: Schema.brand<Schema.String, "PtyID"> & {
129
+ create: () => string & import("effect/Brand").Brand<"PtyID">;
130
+ ascending: (id?: string) => string & import("effect/Brand").Brand<"PtyID">;
131
+ };
132
+ }>>, Schema.toCodecStringTree<Schema.Struct<{
133
+ readonly location: Schema.optional<Schema.Struct<{
134
+ readonly directory: Schema.optional<Schema.String>;
135
+ }>>;
136
+ }>>, never, Schema.toCodecStringTree<Schema.Struct<{
137
+ readonly "x-opencode-ticket": Schema.optional<Schema.String>;
138
+ }>>, Schema.toCodecJson<Schema.Struct<{
139
+ readonly location: Schema.Struct<{
140
+ readonly directory: Schema.brand<Schema.String, "AbsolutePath">;
141
+ }>;
142
+ readonly data: Schema.Struct<{
143
+ readonly ticket: Schema.String;
144
+ readonly expires_in: Schema.Int;
145
+ }>;
146
+ }>>, Schema.toCodecJson<typeof ForbiddenError | typeof PtyNotFoundError>, LocationId, HttpApiMiddleware.Requires<LocationId>> | HttpApiEndpoint.HttpApiEndpoint<"pty.connect", "GET", "/api/pty/:ptyID/connect", Schema.toCodecStringTree<Schema.Struct<{
147
+ ptyID: Schema.brand<Schema.String, "PtyID"> & {
148
+ create: () => string & import("effect/Brand").Brand<"PtyID">;
149
+ ascending: (id?: string) => string & import("effect/Brand").Brand<"PtyID">;
150
+ };
151
+ }>>, never, never, never, Schema.toCodecJson<Schema.Boolean>, Schema.toCodecJson<typeof LocationNotFoundError | typeof ForbiddenError | typeof PtyNotFoundError>, never, never>, false>;
@@ -0,0 +1,112 @@
1
+ import { Pty } from "@opencode/schema/pty";
2
+ import { PtyTicket } from "@opencode/schema/pty-ticket";
3
+ import { Location } from "@opencode/schema/location";
4
+ import { Context, Schema } from "effect";
5
+ import { HttpApiEndpoint, HttpApiGroup, HttpApiMiddleware, HttpApiSchema, OpenApi } from "effect/http-api";
6
+ import { ForbiddenError, LocationNotFoundError, PtyNotFoundError } from "../errors.js";
7
+ import { LocationQuery, locationQueryOpenApi } from "./location.js";
8
+ export const PTY_CONNECT_TICKET_QUERY = "ticket";
9
+ export const PTY_CONNECT_TOKEN_HEADER = "x-opencode-ticket";
10
+ export const PTY_CONNECT_TOKEN_HEADER_VALUE = "1";
11
+ export const PTY_CONNECT_PATH = "/api/pty/:ptyID/connect";
12
+ const PTY_CONNECT_URL = /^\/api\/pty\/[^/]+\/connect$/;
13
+ export function hasPtyConnectTicketURL(url) {
14
+ return PTY_CONNECT_URL.test(url.pathname) && !!url.searchParams.get(PTY_CONNECT_TICKET_QUERY);
15
+ }
16
+ export const makePtyGroup = (locationMiddleware) => HttpApiGroup.make("server.pty")
17
+ .add(HttpApiEndpoint.get("pty.list", "/api/pty", {
18
+ query: LocationQuery,
19
+ success: Location.response(Schema.Array(Pty.Info)),
20
+ })
21
+ .annotateMerge(locationQueryOpenApi)
22
+ .annotateMerge(OpenApi.annotations({
23
+ identifier: "pty.list",
24
+ summary: "List PTY sessions",
25
+ description: "List PTY sessions for a location, including exited sessions retained until removal.",
26
+ })))
27
+ .add(HttpApiEndpoint.post("pty.create", "/api/pty", {
28
+ query: LocationQuery,
29
+ payload: Pty.CreateInput,
30
+ success: Location.response(Pty.Info),
31
+ })
32
+ .annotateMerge(locationQueryOpenApi)
33
+ .annotateMerge(OpenApi.annotations({
34
+ identifier: "pty.create",
35
+ summary: "Create PTY session",
36
+ description: "Create a pseudo-terminal session for a location.",
37
+ })))
38
+ .add(HttpApiEndpoint.get("pty.get", "/api/pty/:ptyID", {
39
+ params: { ptyID: Pty.ID },
40
+ query: LocationQuery,
41
+ success: Location.response(Pty.Info),
42
+ error: PtyNotFoundError,
43
+ })
44
+ .annotateMerge(locationQueryOpenApi)
45
+ .annotateMerge(OpenApi.annotations({
46
+ identifier: "pty.get",
47
+ summary: "Get PTY session",
48
+ description: "Get one PTY session, including its exit code once exited.",
49
+ })))
50
+ .add(HttpApiEndpoint.put("pty.update", "/api/pty/:ptyID", {
51
+ params: { ptyID: Pty.ID },
52
+ query: LocationQuery,
53
+ payload: Pty.UpdateInput,
54
+ success: Location.response(Pty.Info),
55
+ error: PtyNotFoundError,
56
+ })
57
+ .annotateMerge(locationQueryOpenApi)
58
+ .annotateMerge(OpenApi.annotations({
59
+ identifier: "pty.update",
60
+ summary: "Update PTY session",
61
+ description: "Update the title or viewport size of one PTY session.",
62
+ })))
63
+ .add(HttpApiEndpoint.delete("pty.remove", "/api/pty/:ptyID", {
64
+ params: { ptyID: Pty.ID },
65
+ query: LocationQuery,
66
+ success: HttpApiSchema.NoContent,
67
+ error: PtyNotFoundError,
68
+ })
69
+ .annotateMerge(locationQueryOpenApi)
70
+ .annotateMerge(OpenApi.annotations({
71
+ identifier: "pty.remove",
72
+ summary: "Remove PTY session",
73
+ description: "Terminate and remove one PTY session.",
74
+ })))
75
+ .add(HttpApiEndpoint.post("pty.connectToken", "/api/pty/:ptyID/connect-token", {
76
+ params: { ptyID: Pty.ID },
77
+ query: LocationQuery,
78
+ headers: Schema.Struct({ [PTY_CONNECT_TOKEN_HEADER]: Schema.optional(Schema.String) }),
79
+ success: Location.response(PtyTicket.ConnectToken),
80
+ error: [ForbiddenError, PtyNotFoundError],
81
+ })
82
+ .annotateMerge(locationQueryOpenApi)
83
+ .annotateMerge(OpenApi.annotations({
84
+ identifier: "pty.connect.token",
85
+ summary: "Create PTY WebSocket token",
86
+ description: "Create a short-lived single-use ticket for opening a PTY WebSocket connection.",
87
+ })))
88
+ .middleware(locationMiddleware)
89
+ .add(
90
+ // Query fields are decoded in the raw handler before upgrade work.
91
+ HttpApiEndpoint.get("pty.connect", PTY_CONNECT_PATH, {
92
+ params: { ptyID: Pty.ID },
93
+ success: Schema.Boolean,
94
+ error: [ForbiddenError, PtyNotFoundError, LocationNotFoundError],
95
+ }).annotateMerge(OpenApi.annotations({
96
+ identifier: "pty.connect",
97
+ summary: "Connect to PTY session",
98
+ description: "Establish a WebSocket connection streaming PTY output and accepting terminal input.",
99
+ transform: (operation) => ({
100
+ ...operation,
101
+ "x-websocket": true,
102
+ parameters: [
103
+ ...(operation.parameters ?? []),
104
+ ...["location[directory]", "cursor", PTY_CONNECT_TICKET_QUERY].map((name) => ({
105
+ in: "query",
106
+ name,
107
+ schema: { type: "string" },
108
+ })),
109
+ ],
110
+ }),
111
+ })))
112
+ .annotateMerge(OpenApi.annotations({ title: "pty", description: "Experimental location-scoped PTY routes." }));
@@ -0,0 +1,25 @@
1
+ import { Schema } from "effect";
2
+ import { HttpApiEndpoint, HttpApiGroup } from "effect/http-api";
3
+ export declare const ReferenceGroup: HttpApiGroup.HttpApiGroup<"server.reference", HttpApiEndpoint.HttpApiEndpoint<"reference.list", "GET", "/api/reference", never, Schema.toCodecStringTree<Schema.Struct<{
4
+ readonly location: Schema.optional<Schema.Struct<{
5
+ readonly directory: Schema.optional<Schema.String>;
6
+ }>>;
7
+ }>>, never, never, Schema.toCodecJson<Schema.Struct<{
8
+ readonly location: Schema.Struct<{
9
+ readonly directory: Schema.brand<Schema.String, "AbsolutePath">;
10
+ }>;
11
+ readonly data: Schema.$Array<Schema.Struct<{
12
+ readonly name: Schema.String;
13
+ readonly path: Schema.brand<Schema.String, "AbsolutePath">;
14
+ readonly description: Schema.decodeTo<Schema.optional<Schema.toType<Schema.String>>, Schema.optionalKey<Schema.String>, never, never>;
15
+ readonly hidden: Schema.decodeTo<Schema.optional<Schema.toType<Schema.Boolean>>, Schema.optionalKey<Schema.Boolean>, never, never>;
16
+ readonly source: Schema.Union<readonly [Schema.Struct<{
17
+ readonly type: Schema.Literal<"local">;
18
+ readonly path: Schema.brand<Schema.String, "AbsolutePath">;
19
+ }>, Schema.Struct<{
20
+ readonly type: Schema.Literal<"git">;
21
+ readonly repository: Schema.String;
22
+ readonly branch: Schema.decodeTo<Schema.optional<Schema.toType<Schema.String>>, Schema.optionalKey<Schema.String>, never, never>;
23
+ }>]>;
24
+ }>>;
25
+ }>>, never, never, never>, false>;
@@ -0,0 +1,33 @@
1
+ import { Location } from "@opencode/schema/location";
2
+ import { Reference } from "@opencode/schema/reference";
3
+ import { Schema, Struct } from "effect";
4
+ import { HttpApiEndpoint, HttpApiGroup, OpenApi } from "effect/http-api";
5
+ import { LocationQuery, locationQueryOpenApi } from "./location.js";
6
+ const PublicLocalSource = Schema.Struct(Struct.omit(Reference.LocalSource.fields, ["description", "hidden"])).annotate({
7
+ identifier: "Reference.LocalSource",
8
+ });
9
+ const PublicGitSource = Schema.Struct(Struct.omit(Reference.GitSource.fields, ["description", "hidden"])).annotate({
10
+ identifier: "Reference.GitSource",
11
+ });
12
+ const PublicSource = Schema.Union([PublicLocalSource, PublicGitSource])
13
+ .pipe(Schema.toTaggedUnion("type"))
14
+ .annotate({ identifier: "Reference.Source" });
15
+ const PublicInfo = Schema.Struct({
16
+ ...Struct.omit(Reference.Info.fields, ["source"]),
17
+ source: PublicSource,
18
+ }).annotate({ identifier: "Reference.Info" });
19
+ export const ReferenceGroup = HttpApiGroup.make("server.reference")
20
+ .add(HttpApiEndpoint.get("reference.list", "/api/reference", {
21
+ query: LocationQuery,
22
+ success: Location.response(Schema.Array(PublicInfo)),
23
+ })
24
+ .annotateMerge(locationQueryOpenApi)
25
+ .annotateMerge(OpenApi.annotations({
26
+ identifier: "reference.list",
27
+ summary: "List references",
28
+ description: "List references available in the requested location.",
29
+ })))
30
+ .annotateMerge(OpenApi.annotations({
31
+ title: "reference",
32
+ description: "Location-scoped project references.",
33
+ }));
@@ -0,0 +1,21 @@
1
+ import { Schema } from "effect";
2
+ import { HttpApiEndpoint, HttpApiGroup } from "effect/http-api";
3
+ import { RpcError, RpcInternalError } from "../errors.js";
4
+ export declare const RpcInput: Schema.Struct<{
5
+ readonly input: Schema.decodeTo<Schema.optional<Schema.toType<Schema.Unknown>>, Schema.optionalKey<Schema.Unknown>, never, never>;
6
+ }>;
7
+ export declare const RpcOutput: Schema.Struct<{
8
+ readonly output: Schema.optionalKey<Schema.Unknown>;
9
+ }>;
10
+ export declare const RpcGroup: HttpApiGroup.HttpApiGroup<"server.rpc", HttpApiEndpoint.HttpApiEndpoint<"rpc.call", "POST", "/api/rpc/:rpcID/:method", Schema.toCodecStringTree<Schema.Struct<{
11
+ rpcID: Schema.String;
12
+ method: Schema.String;
13
+ }>>, Schema.toCodecStringTree<Schema.Struct<{
14
+ readonly location: Schema.optional<Schema.Struct<{
15
+ readonly directory: Schema.optional<Schema.String>;
16
+ }>>;
17
+ }>>, Schema.toCodecJson<Schema.Struct<{
18
+ readonly input: Schema.decodeTo<Schema.optional<Schema.toType<Schema.Unknown>>, Schema.optionalKey<Schema.Unknown>, never, never>;
19
+ }>>, never, Schema.toCodecJson<Schema.Struct<{
20
+ readonly output: Schema.optionalKey<Schema.Unknown>;
21
+ }>>, Schema.toCodecJson<typeof RpcError | typeof RpcInternalError>, never, never>, false>;
@@ -0,0 +1,24 @@
1
+ import { optional } from "@opencode/schema/schema";
2
+ import { Schema } from "effect";
3
+ import { HttpApiEndpoint, HttpApiGroup, OpenApi } from "effect/http-api";
4
+ import { RpcError, RpcInternalError } from "../errors.js";
5
+ import { LocationQuery, locationQueryOpenApi } from "./location.js";
6
+ export const RpcInput = Schema.Struct({ input: optional(Schema.Unknown) }).annotate({ identifier: "Rpc.Input" });
7
+ export const RpcOutput = Schema.Struct({ output: Schema.optionalKey(Schema.Unknown) }).annotate({
8
+ identifier: "Rpc.Output",
9
+ });
10
+ export const RpcGroup = HttpApiGroup.make("server.rpc")
11
+ .add(HttpApiEndpoint.post("rpc.call", "/api/rpc/:rpcID/:method", {
12
+ params: { rpcID: Schema.String, method: Schema.String },
13
+ query: LocationQuery,
14
+ payload: RpcInput,
15
+ success: RpcOutput,
16
+ error: [RpcError, RpcInternalError],
17
+ })
18
+ .annotateMerge(locationQueryOpenApi)
19
+ .annotateMerge(OpenApi.annotations({
20
+ identifier: "rpc.call",
21
+ summary: "Call a plugin RPC",
22
+ description: "Dispatch a method to the currently registered RPC at the requested location.",
23
+ })))
24
+ .annotateMerge(OpenApi.annotations({ title: "rpc", description: "Plugin RPC routes." }));
@@ -0,0 +1,44 @@
1
+ import { Schema } from "effect";
2
+ import { HttpApiEndpoint, HttpApiGroup } from "effect/http-api";
3
+ import { UnauthorizedError } from "../errors.js";
4
+ export declare const ServerInfo: Schema.Struct<{
5
+ readonly version: Schema.String;
6
+ readonly pid: Schema.Int;
7
+ readonly urls: Schema.$Array<Schema.String>;
8
+ readonly paths: Schema.Struct<{
9
+ readonly tmp: Schema.String;
10
+ }>;
11
+ readonly capabilities: Schema.optional<Schema.Struct<{
12
+ readonly persistentPty: Schema.optional<Schema.Boolean>;
13
+ }>>;
14
+ }>;
15
+ export type ServerInfo = typeof ServerInfo.Type;
16
+ export declare const PairingCode: Schema.Struct<{
17
+ readonly code: Schema.String;
18
+ readonly expires_in: Schema.Int;
19
+ }>;
20
+ export type PairingCode = typeof PairingCode.Type;
21
+ export declare const PairingSession: Schema.Struct<{
22
+ readonly token: Schema.String;
23
+ }>;
24
+ export type PairingSession = typeof PairingSession.Type;
25
+ export declare const PAIRING_CONNECT_PATH = "/auth/connect/:code";
26
+ export declare function isPairingConnectURL(url: URL): boolean;
27
+ export declare const ServerGroup: HttpApiGroup.HttpApiGroup<"server.server", HttpApiEndpoint.HttpApiEndpoint<"server.connect", "GET", "/auth/connect/:code", Schema.toCodecStringTree<Schema.Struct<{
28
+ code: Schema.String;
29
+ }>>, never, never, never, Schema.toCodecJson<Schema.Struct<{
30
+ readonly token: Schema.String;
31
+ }>>, Schema.toCodecJson<typeof UnauthorizedError>, never, never> | HttpApiEndpoint.HttpApiEndpoint<"server.info", "GET", "/api/info", never, never, never, never, Schema.toCodecJson<Schema.Struct<{
32
+ readonly version: Schema.String;
33
+ readonly pid: Schema.Int;
34
+ readonly urls: Schema.$Array<Schema.String>;
35
+ readonly paths: Schema.Struct<{
36
+ readonly tmp: Schema.String;
37
+ }>;
38
+ readonly capabilities: Schema.optional<Schema.Struct<{
39
+ readonly persistentPty: Schema.optional<Schema.Boolean>;
40
+ }>>;
41
+ }>>, never, never, never> | HttpApiEndpoint.HttpApiEndpoint<"server.pair", "POST", "/api/pair", never, never, never, never, Schema.toCodecJson<Schema.Struct<{
42
+ readonly code: Schema.String;
43
+ readonly expires_in: Schema.Int;
44
+ }>>, never, never, never>, false>;
@@ -0,0 +1,53 @@
1
+ import { Schema } from "effect";
2
+ import { HttpApiEndpoint, HttpApiGroup, OpenApi } from "effect/http-api";
3
+ import { UnauthorizedError } from "../errors.js";
4
+ export const ServerInfo = Schema.Struct({
5
+ version: Schema.String,
6
+ // 0 means the runtime has no OS process identity (e.g. workerd).
7
+ pid: Schema.Int.check(Schema.isGreaterThanOrEqualTo(0)),
8
+ urls: Schema.Array(Schema.String),
9
+ paths: Schema.Struct({
10
+ tmp: Schema.String,
11
+ }),
12
+ // Optional at every level so clients still decode servers that predate a capability.
13
+ capabilities: Schema.optional(Schema.Struct({
14
+ persistentPty: Schema.optional(Schema.Boolean),
15
+ })),
16
+ }).annotate({ identifier: "ServerInfo" });
17
+ export const PairingCode = Schema.Struct({
18
+ code: Schema.String,
19
+ expires_in: Schema.Int,
20
+ }).annotate({ identifier: "PairingCode" });
21
+ export const PairingSession = Schema.Struct({
22
+ token: Schema.String,
23
+ }).annotate({ identifier: "PairingSession" });
24
+ export const PAIRING_CONNECT_PATH = "/auth/connect/:code";
25
+ const PAIRING_CONNECT_URL = /^\/auth\/connect\/[^/]+$/;
26
+ export function isPairingConnectURL(url) {
27
+ return PAIRING_CONNECT_URL.test(url.pathname);
28
+ }
29
+ export const ServerGroup = HttpApiGroup.make("server.server")
30
+ .add(HttpApiEndpoint.get("server.info", "/api/info", {
31
+ success: ServerInfo,
32
+ }).annotateMerge(OpenApi.annotations({
33
+ identifier: "server.info",
34
+ summary: "Get server info",
35
+ description: "Return the server identity, connection URLs, paths, and readiness status.",
36
+ })))
37
+ .add(HttpApiEndpoint.post("server.pair", "/api/pair", {
38
+ success: PairingCode,
39
+ }).annotateMerge(OpenApi.annotations({
40
+ identifier: "server.pair",
41
+ summary: "Create pairing code",
42
+ description: "Create a short-lived, single-use code for a /auth/connect/:code pairing link.",
43
+ })))
44
+ .add(HttpApiEndpoint.get("server.connect", PAIRING_CONNECT_PATH, {
45
+ params: { code: Schema.String },
46
+ success: PairingSession,
47
+ error: UnauthorizedError,
48
+ }).annotateMerge(OpenApi.annotations({
49
+ identifier: "server.connect",
50
+ summary: "Redeem pairing code",
51
+ description: "Redeem a pairing code. Browsers receive a session cookie and a redirect to the web app; requests that accept JSON receive a session token to use as the password.",
52
+ })))
53
+ .annotateMerge(OpenApi.annotations({ title: "server" }));