@opencode/server 2.0.3 → 2.0.5
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 +63 -38
- package/dist/handlers/config.js +4 -9
- package/dist/handlers/credential.d.ts +2 -1
- package/dist/handlers/credential.js +4 -4
- package/dist/handlers/form.d.ts +1 -4
- package/dist/handlers/form.js +6 -58
- package/dist/handlers/integration.js +69 -11
- package/dist/handlers/location.js +0 -1
- package/dist/handlers/model.js +5 -5
- package/dist/handlers/permission.d.ts +1 -1
- package/dist/handlers/permission.js +1 -4
- package/dist/handlers/plugin.js +3 -7
- package/dist/handlers/project.d.ts +1 -1
- package/dist/handlers/project.js +1 -6
- package/dist/handlers/provider.js +4 -4
- package/dist/handlers/server.js +7 -2
- package/dist/handlers/session.d.ts +1 -1
- package/dist/handlers/session.js +60 -20
- package/dist/handlers/shell.js +1 -4
- package/dist/handlers/vcs.js +1 -1
- package/dist/handlers/worktree.d.ts +2 -1
- package/dist/handlers/worktree.js +10 -12
- package/dist/handlers.d.ts +1 -1
- package/dist/handlers.js +1 -3
- package/dist/location.js +2 -5
- package/dist/process.js +14 -14
- package/dist/routes.d.ts +3 -2
- package/dist/routes.js +3 -1
- package/package.json +8 -8
- package/dist/handlers/health.d.ts +0 -2
- package/dist/handlers/health.js +0 -11
- package/dist/handlers/workspace.d.ts +0 -2
- package/dist/handlers/workspace.js +0 -20
package/dist/api.d.ts
CHANGED
|
@@ -145,7 +145,7 @@ export declare const Api: import("@opencode/protocol/api").Api<LocationMiddlewar
|
|
|
145
145
|
};
|
|
146
146
|
readonly created: import("effect/Schema").Finite;
|
|
147
147
|
readonly metadata: import("effect/Schema").decodeTo<import("effect/Schema").optional<import("effect/Schema").toType<import("effect/Schema").$Record<import("effect/Schema").String, import("effect/Schema").Unknown>>>, import("effect/Schema").optionalKey<import("effect/Schema").$Record<import("effect/Schema").String, import("effect/Schema").Unknown>>, never, never>;
|
|
148
|
-
readonly type: import("effect/Schema").Literal<"
|
|
148
|
+
readonly type: import("effect/Schema").Literal<"provider.updated">;
|
|
149
149
|
readonly location: import("effect/Schema").decodeTo<import("effect/Schema").optional<import("effect/Schema").toType<import("effect/Schema").Struct<{
|
|
150
150
|
readonly directory: import("effect/Schema").brand<import("effect/Schema").String, "AbsolutePath">;
|
|
151
151
|
readonly workspaceID: import("effect/Schema").decodeTo<import("effect/Schema").optional<import("effect/Schema").toType<import("effect/Schema").brand<import("effect/Schema").String, "Workspace.ID"> & {
|
|
@@ -167,7 +167,39 @@ export declare const Api: import("@opencode/protocol/api").Api<LocationMiddlewar
|
|
|
167
167
|
}>>, never, never>;
|
|
168
168
|
readonly data: import("effect/Schema").Struct<{}>;
|
|
169
169
|
}> & {
|
|
170
|
-
type: "
|
|
170
|
+
type: "provider.updated";
|
|
171
|
+
durability: "ephemeral";
|
|
172
|
+
durable: undefined;
|
|
173
|
+
data: import("effect/Schema").Struct<{}>;
|
|
174
|
+
}, import("effect/Schema").Struct<{
|
|
175
|
+
readonly id: import("effect/Schema").brand<import("effect/Schema").String, "Event.ID"> & {
|
|
176
|
+
create: () => string & import("effect/Brand").Brand<"Event.ID">;
|
|
177
|
+
};
|
|
178
|
+
readonly created: import("effect/Schema").Finite;
|
|
179
|
+
readonly metadata: import("effect/Schema").decodeTo<import("effect/Schema").optional<import("effect/Schema").toType<import("effect/Schema").$Record<import("effect/Schema").String, import("effect/Schema").Unknown>>>, import("effect/Schema").optionalKey<import("effect/Schema").$Record<import("effect/Schema").String, import("effect/Schema").Unknown>>, never, never>;
|
|
180
|
+
readonly type: import("effect/Schema").Literal<"model.updated">;
|
|
181
|
+
readonly location: import("effect/Schema").decodeTo<import("effect/Schema").optional<import("effect/Schema").toType<import("effect/Schema").Struct<{
|
|
182
|
+
readonly directory: import("effect/Schema").brand<import("effect/Schema").String, "AbsolutePath">;
|
|
183
|
+
readonly workspaceID: import("effect/Schema").decodeTo<import("effect/Schema").optional<import("effect/Schema").toType<import("effect/Schema").brand<import("effect/Schema").String, "Workspace.ID"> & {
|
|
184
|
+
ascending: (id?: string) => string & import("effect/Brand").Brand<"Workspace.ID">;
|
|
185
|
+
create: () => string & import("effect/Brand").Brand<"Workspace.ID">;
|
|
186
|
+
}>>, import("effect/Schema").optionalKey<import("effect/Schema").brand<import("effect/Schema").String, "Workspace.ID"> & {
|
|
187
|
+
ascending: (id?: string) => string & import("effect/Brand").Brand<"Workspace.ID">;
|
|
188
|
+
create: () => string & import("effect/Brand").Brand<"Workspace.ID">;
|
|
189
|
+
}>, never, never>;
|
|
190
|
+
}>>>, import("effect/Schema").optionalKey<import("effect/Schema").Struct<{
|
|
191
|
+
readonly directory: import("effect/Schema").brand<import("effect/Schema").String, "AbsolutePath">;
|
|
192
|
+
readonly workspaceID: import("effect/Schema").decodeTo<import("effect/Schema").optional<import("effect/Schema").toType<import("effect/Schema").brand<import("effect/Schema").String, "Workspace.ID"> & {
|
|
193
|
+
ascending: (id?: string) => string & import("effect/Brand").Brand<"Workspace.ID">;
|
|
194
|
+
create: () => string & import("effect/Brand").Brand<"Workspace.ID">;
|
|
195
|
+
}>>, import("effect/Schema").optionalKey<import("effect/Schema").brand<import("effect/Schema").String, "Workspace.ID"> & {
|
|
196
|
+
ascending: (id?: string) => string & import("effect/Brand").Brand<"Workspace.ID">;
|
|
197
|
+
create: () => string & import("effect/Brand").Brand<"Workspace.ID">;
|
|
198
|
+
}>, never, never>;
|
|
199
|
+
}>>, never, never>;
|
|
200
|
+
readonly data: import("effect/Schema").Struct<{}>;
|
|
201
|
+
}> & {
|
|
202
|
+
type: "model.updated";
|
|
171
203
|
durability: "ephemeral";
|
|
172
204
|
durable: undefined;
|
|
173
205
|
data: import("effect/Schema").Struct<{}>;
|
|
@@ -789,7 +821,7 @@ export declare const Api: import("@opencode/protocol/api").Api<LocationMiddlewar
|
|
|
789
821
|
};
|
|
790
822
|
readonly created: import("effect/Schema").Finite;
|
|
791
823
|
readonly metadata: import("effect/Schema").decodeTo<import("effect/Schema").optional<import("effect/Schema").toType<import("effect/Schema").$Record<import("effect/Schema").String, import("effect/Schema").Unknown>>>, import("effect/Schema").optionalKey<import("effect/Schema").$Record<import("effect/Schema").String, import("effect/Schema").Unknown>>, never, never>;
|
|
792
|
-
readonly type: import("effect/Schema").Literal<"session.permissions
|
|
824
|
+
readonly type: import("effect/Schema").Literal<"session.permissions">;
|
|
793
825
|
readonly durable: import("effect/Schema").Struct<{
|
|
794
826
|
readonly aggregateID: import("effect/Schema").String;
|
|
795
827
|
readonly seq: import("effect/Schema").brand<import("effect/Schema").Int, "Event.Seq">;
|
|
@@ -826,7 +858,7 @@ export declare const Api: import("@opencode/protocol/api").Api<LocationMiddlewar
|
|
|
826
858
|
};
|
|
827
859
|
}>;
|
|
828
860
|
}> & {
|
|
829
|
-
type: "session.permissions
|
|
861
|
+
type: "session.permissions";
|
|
830
862
|
durability: "durable";
|
|
831
863
|
durable: {
|
|
832
864
|
readonly version: number;
|
|
@@ -4541,7 +4573,6 @@ export declare const Api: import("@opencode/protocol/api").Api<LocationMiddlewar
|
|
|
4541
4573
|
readonly time: import("effect/Schema").Struct<{
|
|
4542
4574
|
readonly created: import("effect/Schema").Int;
|
|
4543
4575
|
readonly updated: import("effect/Schema").Int;
|
|
4544
|
-
readonly initialized: import("effect/Schema").decodeTo<import("effect/Schema").optional<import("effect/Schema").toType<import("effect/Schema").Int>>, import("effect/Schema").optionalKey<import("effect/Schema").Int>, never, never>;
|
|
4545
4576
|
}>;
|
|
4546
4577
|
readonly sandboxes: import("effect/Schema").$Array<import("effect/Schema").String>;
|
|
4547
4578
|
}>;
|
|
@@ -4573,7 +4604,6 @@ export declare const Api: import("@opencode/protocol/api").Api<LocationMiddlewar
|
|
|
4573
4604
|
readonly time: import("effect/Schema").Struct<{
|
|
4574
4605
|
readonly created: import("effect/Schema").Int;
|
|
4575
4606
|
readonly updated: import("effect/Schema").Int;
|
|
4576
|
-
readonly initialized: import("effect/Schema").decodeTo<import("effect/Schema").optional<import("effect/Schema").toType<import("effect/Schema").Int>>, import("effect/Schema").optionalKey<import("effect/Schema").Int>, never, never>;
|
|
4577
4607
|
}>;
|
|
4578
4608
|
readonly sandboxes: import("effect/Schema").$Array<import("effect/Schema").String>;
|
|
4579
4609
|
}>;
|
|
@@ -6156,13 +6186,6 @@ export declare const Api: import("@opencode/protocol/api").Api<LocationMiddlewar
|
|
|
6156
6186
|
readonly type: import("effect/Schema").TemplateLiteral<readonly ["rpc.", import("effect/Schema").String]>;
|
|
6157
6187
|
readonly location: import("effect/Schema").Struct<{
|
|
6158
6188
|
readonly directory: import("effect/Schema").brand<import("effect/Schema").String, "AbsolutePath">;
|
|
6159
|
-
readonly workspaceID: import("effect/Schema").decodeTo<import("effect/Schema").optional<import("effect/Schema").toType<import("effect/Schema").brand<import("effect/Schema").String, "Workspace.ID"> & {
|
|
6160
|
-
ascending: (id?: string) => string & import("effect/Brand").Brand<"Workspace.ID">;
|
|
6161
|
-
create: () => string & import("effect/Brand").Brand<"Workspace.ID">;
|
|
6162
|
-
}>>, import("effect/Schema").optionalKey<import("effect/Schema").brand<import("effect/Schema").String, "Workspace.ID"> & {
|
|
6163
|
-
ascending: (id?: string) => string & import("effect/Brand").Brand<"Workspace.ID">;
|
|
6164
|
-
create: () => string & import("effect/Brand").Brand<"Workspace.ID">;
|
|
6165
|
-
}>, never, never>;
|
|
6166
6189
|
}>;
|
|
6167
6190
|
readonly data: import("effect/Schema").$Record<import("effect/Schema").String, import("effect/Schema").Unknown>;
|
|
6168
6191
|
}>, ...import("effect/Schema").Struct<{
|
|
@@ -6174,13 +6197,6 @@ export declare const Api: import("@opencode/protocol/api").Api<LocationMiddlewar
|
|
|
6174
6197
|
readonly metadata: import("effect/Schema").optional<import("effect/Schema").$Record<import("effect/Schema").String, import("effect/Schema").Unknown>>;
|
|
6175
6198
|
readonly location: import("effect/Schema").optional<import("effect/Schema").Struct<{
|
|
6176
6199
|
readonly directory: import("effect/Schema").brand<import("effect/Schema").String, "AbsolutePath">;
|
|
6177
|
-
readonly workspaceID: import("effect/Schema").decodeTo<import("effect/Schema").optional<import("effect/Schema").toType<import("effect/Schema").brand<import("effect/Schema").String, "Workspace.ID"> & {
|
|
6178
|
-
ascending: (id?: string) => string & import("effect/Brand").Brand<"Workspace.ID">;
|
|
6179
|
-
create: () => string & import("effect/Brand").Brand<"Workspace.ID">;
|
|
6180
|
-
}>>, import("effect/Schema").optionalKey<import("effect/Schema").brand<import("effect/Schema").String, "Workspace.ID"> & {
|
|
6181
|
-
ascending: (id?: string) => string & import("effect/Brand").Brand<"Workspace.ID">;
|
|
6182
|
-
create: () => string & import("effect/Brand").Brand<"Workspace.ID">;
|
|
6183
|
-
}>, never, never>;
|
|
6184
6200
|
}>>;
|
|
6185
6201
|
}>[]]>>, import("effect/Schema").Never, {
|
|
6186
6202
|
readonly id: string & import("effect/Brand").Brand<"Event.ID">;
|
|
@@ -6199,8 +6215,6 @@ export declare const Api: import("@opencode/protocol/api").Api<LocationMiddlewar
|
|
|
6199
6215
|
readonly data: {
|
|
6200
6216
|
readonly form: {
|
|
6201
6217
|
readonly id: string & import("effect/Brand").Brand<"Form.ID">;
|
|
6202
|
-
readonly sessionID: string;
|
|
6203
|
-
readonly title: string;
|
|
6204
6218
|
readonly fields: readonly [{
|
|
6205
6219
|
readonly type: "string";
|
|
6206
6220
|
readonly key: string;
|
|
@@ -6380,6 +6394,8 @@ export declare const Api: import("@opencode/protocol/api").Api<LocationMiddlewar
|
|
|
6380
6394
|
readonly description?: string | undefined;
|
|
6381
6395
|
readonly title?: string | undefined;
|
|
6382
6396
|
})[]];
|
|
6397
|
+
readonly sessionID: string;
|
|
6398
|
+
readonly title: string;
|
|
6383
6399
|
readonly metadata?: {
|
|
6384
6400
|
readonly [x: string]: unknown;
|
|
6385
6401
|
} | undefined;
|
|
@@ -6466,6 +6482,30 @@ export declare const Api: import("@opencode/protocol/api").Api<LocationMiddlewar
|
|
|
6466
6482
|
readonly metadata?: {
|
|
6467
6483
|
readonly [x: string]: unknown;
|
|
6468
6484
|
} | undefined;
|
|
6485
|
+
} | {
|
|
6486
|
+
readonly id: string & import("effect/Brand").Brand<"Event.ID">;
|
|
6487
|
+
readonly data: {};
|
|
6488
|
+
readonly type: "provider.updated";
|
|
6489
|
+
readonly created: number;
|
|
6490
|
+
readonly location?: {
|
|
6491
|
+
readonly directory: string & import("effect/Brand").Brand<"AbsolutePath">;
|
|
6492
|
+
readonly workspaceID?: (string & import("effect/Brand").Brand<"Workspace.ID">) | undefined;
|
|
6493
|
+
} | undefined;
|
|
6494
|
+
readonly metadata?: {
|
|
6495
|
+
readonly [x: string]: unknown;
|
|
6496
|
+
} | undefined;
|
|
6497
|
+
} | {
|
|
6498
|
+
readonly id: string & import("effect/Brand").Brand<"Event.ID">;
|
|
6499
|
+
readonly data: {};
|
|
6500
|
+
readonly type: "model.updated";
|
|
6501
|
+
readonly created: number;
|
|
6502
|
+
readonly location?: {
|
|
6503
|
+
readonly directory: string & import("effect/Brand").Brand<"AbsolutePath">;
|
|
6504
|
+
readonly workspaceID?: (string & import("effect/Brand").Brand<"Workspace.ID">) | undefined;
|
|
6505
|
+
} | undefined;
|
|
6506
|
+
readonly metadata?: {
|
|
6507
|
+
readonly [x: string]: unknown;
|
|
6508
|
+
} | undefined;
|
|
6469
6509
|
} | {
|
|
6470
6510
|
readonly id: string & import("effect/Brand").Brand<"Event.ID">;
|
|
6471
6511
|
readonly data: {
|
|
@@ -6529,7 +6569,6 @@ export declare const Api: import("@opencode/protocol/api").Api<LocationMiddlewar
|
|
|
6529
6569
|
readonly time: {
|
|
6530
6570
|
readonly created: number;
|
|
6531
6571
|
readonly updated: number;
|
|
6532
|
-
readonly initialized?: number | undefined;
|
|
6533
6572
|
};
|
|
6534
6573
|
readonly sandboxes: readonly string[];
|
|
6535
6574
|
readonly name?: string | undefined;
|
|
@@ -6765,7 +6804,7 @@ export declare const Api: import("@opencode/protocol/api").Api<LocationMiddlewar
|
|
|
6765
6804
|
readonly seq: number & import("effect/Brand").Brand<"Event.Seq">;
|
|
6766
6805
|
readonly version: number & import("effect/Brand").Brand<"Event.Version">;
|
|
6767
6806
|
};
|
|
6768
|
-
readonly type: "session.permissions
|
|
6807
|
+
readonly type: "session.permissions";
|
|
6769
6808
|
readonly created: number;
|
|
6770
6809
|
readonly location?: {
|
|
6771
6810
|
readonly directory: string & import("effect/Brand").Brand<"AbsolutePath">;
|
|
@@ -7959,18 +7998,6 @@ export declare const Api: import("@opencode/protocol/api").Api<LocationMiddlewar
|
|
|
7959
7998
|
readonly metadata?: {
|
|
7960
7999
|
readonly [x: string]: unknown;
|
|
7961
8000
|
} | undefined;
|
|
7962
|
-
} | {
|
|
7963
|
-
readonly id: string & import("effect/Brand").Brand<"Event.ID">;
|
|
7964
|
-
readonly data: {};
|
|
7965
|
-
readonly type: "catalog.updated";
|
|
7966
|
-
readonly created: number;
|
|
7967
|
-
readonly location?: {
|
|
7968
|
-
readonly directory: string & import("effect/Brand").Brand<"AbsolutePath">;
|
|
7969
|
-
readonly workspaceID?: (string & import("effect/Brand").Brand<"Workspace.ID">) | undefined;
|
|
7970
|
-
} | undefined;
|
|
7971
|
-
readonly metadata?: {
|
|
7972
|
-
readonly [x: string]: unknown;
|
|
7973
|
-
} | undefined;
|
|
7974
8001
|
} | {
|
|
7975
8002
|
readonly id: string & import("effect/Brand").Brand<"Event.ID">;
|
|
7976
8003
|
readonly data: {};
|
|
@@ -8370,7 +8397,6 @@ export declare const Api: import("@opencode/protocol/api").Api<LocationMiddlewar
|
|
|
8370
8397
|
readonly id: string & import("effect/Brand").Brand<"Event.ID">;
|
|
8371
8398
|
readonly location: {
|
|
8372
8399
|
readonly directory: string & import("effect/Brand").Brand<"AbsolutePath">;
|
|
8373
|
-
readonly workspaceID?: (string & import("effect/Brand").Brand<"Workspace.ID">) | undefined;
|
|
8374
8400
|
};
|
|
8375
8401
|
readonly data: {
|
|
8376
8402
|
readonly [x: string]: unknown;
|
|
@@ -8386,7 +8412,6 @@ export declare const Api: import("@opencode/protocol/api").Api<LocationMiddlewar
|
|
|
8386
8412
|
readonly type: "server.connected";
|
|
8387
8413
|
readonly location?: {
|
|
8388
8414
|
readonly directory: string & import("effect/Brand").Brand<"AbsolutePath">;
|
|
8389
|
-
readonly workspaceID?: (string & import("effect/Brand").Brand<"Workspace.ID">) | undefined;
|
|
8390
8415
|
} | undefined;
|
|
8391
8416
|
readonly metadata?: {
|
|
8392
8417
|
readonly [x: string]: unknown;
|
package/dist/handlers/config.js
CHANGED
|
@@ -3,16 +3,11 @@ import { ShellSelect } from "@opencode/core/shell/select";
|
|
|
3
3
|
import { Effect } from "effect";
|
|
4
4
|
import { HttpApiBuilder } from "effect/unstable/httpapi";
|
|
5
5
|
import { Api } from "../api";
|
|
6
|
-
export const ConfigHandler = HttpApiBuilder.group(Api, "server.config", (handlers) => handlers.handle("config.get", () => Config.Service.use((config) => config.entries())).handle("config.
|
|
6
|
+
export const ConfigHandler = HttpApiBuilder.group(Api, "server.config", (handlers) => handlers.handle("config.get", () => Config.Service.use((config) => config.entries())).handle("config.update", Effect.fn(function* (ctx) {
|
|
7
7
|
const config = yield* Config.Service;
|
|
8
|
-
if (!config.
|
|
9
|
-
return yield* Effect.die(Error("Config
|
|
10
|
-
return yield* config.
|
|
11
|
-
})).handle("config.updatePreferences", Effect.fn(function* (ctx) {
|
|
12
|
-
const config = yield* Config.Service;
|
|
13
|
-
if (!config.updatePreferences)
|
|
14
|
-
return yield* Effect.die(Error("Config preference updates are unavailable"));
|
|
15
|
-
return yield* config.updatePreferences(ctx.payload).pipe(Effect.orDie);
|
|
8
|
+
if (!config.update)
|
|
9
|
+
return yield* Effect.die(Error("Config updates are unavailable"));
|
|
10
|
+
return yield* config.update(ctx.payload).pipe(Effect.orDie);
|
|
16
11
|
})).handle("config.shells", Effect.fn(function* () {
|
|
17
12
|
const shell = yield* ShellSelect.Service;
|
|
18
13
|
if (!shell.list)
|
|
@@ -1 +1,2 @@
|
|
|
1
|
-
|
|
1
|
+
import { Credential } from "@opencode/core/credential";
|
|
2
|
+
export declare const CredentialHandler: import("effect/Layer").Layer<import("effect/unstable/httpapi/HttpApiGroup").Service<"server", "server.credential">, never, import("@opencode/protocol/middleware/schema-error").SchemaErrorMiddleware | import("@opencode/protocol/middleware/authorization").Authorization | import("effect/unstable/http/HttpRouter").Request<"Requires", Credential.Service>>;
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Credential } from "@opencode/core/credential";
|
|
2
2
|
import { Effect } from "effect";
|
|
3
3
|
import { HttpApiBuilder, HttpApiSchema } from "effect/unstable/httpapi";
|
|
4
4
|
import { Api } from "../api";
|
|
5
5
|
export const CredentialHandler = HttpApiBuilder.group(Api, "server.credential", (handlers) => handlers.handle("credential.update", Effect.fn(function* (ctx) {
|
|
6
|
-
yield* (yield*
|
|
6
|
+
yield* (yield* Credential.Service).update(ctx.params.credentialID, { label: ctx.payload.label });
|
|
7
7
|
return HttpApiSchema.NoContent.make();
|
|
8
8
|
})).handle("credential.activate", Effect.fn(function* (ctx) {
|
|
9
|
-
yield* (yield*
|
|
9
|
+
yield* (yield* Credential.Service).activate(ctx.params.credentialID);
|
|
10
10
|
return HttpApiSchema.NoContent.make();
|
|
11
11
|
})).handle("credential.remove", Effect.fn(function* (ctx) {
|
|
12
|
-
yield* (yield*
|
|
12
|
+
yield* (yield* Credential.Service).remove(ctx.params.credentialID);
|
|
13
13
|
return HttpApiSchema.NoContent.make();
|
|
14
14
|
})));
|
package/dist/handlers/form.d.ts
CHANGED
|
@@ -1,4 +1 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { LocationServiceMap } from "@opencode/core/location-services";
|
|
3
|
-
import { Session } from "@opencode/core/session";
|
|
4
|
-
export declare const FormHandler: import("effect/Layer").Layer<import("effect/unstable/httpapi/HttpApiGroup").Service<"server", "server.form">, never, LocationServiceMap.Service | Session.Service | Instance.Service | import("../location").LocationMiddleware | (import("@opencode/protocol/middleware/schema-error").SchemaErrorMiddleware | import("@opencode/protocol/middleware/authorization").Authorization | import("../middleware/form-location").FormLocationMiddleware)>;
|
|
1
|
+
export declare const FormHandler: import("effect/Layer").Layer<import("effect/unstable/httpapi/HttpApiGroup").Service<"server", "server.form">, never, import("@opencode/protocol/middleware/schema-error").SchemaErrorMiddleware | import("@opencode/protocol/middleware/authorization").Authorization | import("../location").LocationMiddleware>;
|
package/dist/handlers/form.js
CHANGED
|
@@ -1,61 +1,9 @@
|
|
|
1
1
|
import { Form } from "@opencode/core/form";
|
|
2
|
-
import { Instance } from "@opencode/core/instance/service";
|
|
3
|
-
import { LocationServiceMap } from "@opencode/core/location-services";
|
|
4
|
-
import { Session } from "@opencode/core/session";
|
|
5
|
-
import {
|
|
6
|
-
ConflictError,
|
|
7
|
-
FormAlreadySettledError,
|
|
8
|
-
FormInvalidAnswerError,
|
|
9
|
-
FormNotFoundError,
|
|
10
|
-
InvalidRequestError
|
|
11
|
-
} from "@opencode/protocol/errors";
|
|
12
2
|
import { Effect } from "effect";
|
|
13
|
-
import { HttpApiBuilder
|
|
3
|
+
import { HttpApiBuilder } from "effect/unstable/httpapi";
|
|
14
4
|
import { Api } from "../api";
|
|
15
|
-
import {
|
|
16
|
-
function
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
const locations = yield* LocationServiceMap.Service, instances = yield* Instance.Service, sessions = yield* Session.Service, requireOwnedForm = Effect.fnUntraced(function* (sessionID, formID) {
|
|
21
|
-
const form = yield* Form.Service, info = yield* form.get(formID).pipe(Effect.catchTag("Form.NotFoundError", () => missingForm(formID)));
|
|
22
|
-
if (info.sessionID !== sessionID)
|
|
23
|
-
return yield* missingForm(formID);
|
|
24
|
-
return { form, info };
|
|
25
|
-
});
|
|
26
|
-
return handlers.handle("form.request.list", Effect.fn(function* () {
|
|
27
|
-
const form = yield* Form.Service;
|
|
28
|
-
return yield* response(form.list());
|
|
29
|
-
})).handle("session.form.list", Effect.fn(function* (ctx) {
|
|
30
|
-
const session = ctx.params.sessionID === "global" ? void 0 : yield* sessionInfo(sessions, ctx.params.sessionID), read = Form.Service.use((form) => form.list({ sessionID: ctx.params.sessionID }));
|
|
31
|
-
return { data: yield* session ? read.pipe(instances.provide(session)) : read.pipe(Effect.provide(locations.get(requestRef(ctx.request)))) };
|
|
32
|
-
})).handle("session.form.create", Effect.fn(function* (ctx) {
|
|
33
|
-
return { data: yield* (yield* Form.Service).create({
|
|
34
|
-
id: ctx.payload.id,
|
|
35
|
-
sessionID: ctx.params.sessionID,
|
|
36
|
-
title: ctx.payload.title,
|
|
37
|
-
metadata: ctx.payload.metadata,
|
|
38
|
-
fields: ctx.payload.fields
|
|
39
|
-
}).pipe(Effect.catchTags({
|
|
40
|
-
"Form.AlreadyExistsError": (error) => new ConflictError({ resource: error.id, message: error.message }),
|
|
41
|
-
"Form.InvalidFormError": (error) => new InvalidRequestError({ message: error.message, field: "fields" })
|
|
42
|
-
})) };
|
|
43
|
-
})).handle("session.form.get", Effect.fn(function* (ctx) {
|
|
44
|
-
return { data: (yield* requireOwnedForm(ctx.params.sessionID, ctx.params.formID)).info };
|
|
45
|
-
})).handle("session.form.state", Effect.fn(function* (ctx) {
|
|
46
|
-
return { data: yield* (yield* requireOwnedForm(ctx.params.sessionID, ctx.params.formID)).form.state(ctx.params.formID).pipe(Effect.catchTag("Form.NotFoundError", () => missingForm(ctx.params.formID))) };
|
|
47
|
-
})).handle("session.form.reply", Effect.fn(function* (ctx) {
|
|
48
|
-
yield* (yield* requireOwnedForm(ctx.params.sessionID, ctx.params.formID)).form.reply({ id: ctx.params.formID, answer: ctx.payload.answer }).pipe(Effect.catchTags({
|
|
49
|
-
"Form.AlreadySettledError": (error) => new FormAlreadySettledError({ id: error.id, message: error.message }),
|
|
50
|
-
"Form.InvalidAnswerError": (error) => new FormInvalidAnswerError({ id: error.id, message: error.message }),
|
|
51
|
-
"Form.NotFoundError": () => missingForm(ctx.params.formID)
|
|
52
|
-
}));
|
|
53
|
-
return HttpApiSchema.NoContent.make();
|
|
54
|
-
})).handle("session.form.cancel", Effect.fn(function* (ctx) {
|
|
55
|
-
yield* (yield* requireOwnedForm(ctx.params.sessionID, ctx.params.formID)).form.cancel(ctx.params.formID).pipe(Effect.catchTags({
|
|
56
|
-
"Form.AlreadySettledError": (error) => new FormAlreadySettledError({ id: error.id, message: error.message }),
|
|
57
|
-
"Form.NotFoundError": () => missingForm(ctx.params.formID)
|
|
58
|
-
}));
|
|
59
|
-
return HttpApiSchema.NoContent.make();
|
|
60
|
-
}));
|
|
61
|
-
}));
|
|
5
|
+
import { response } from "../location";
|
|
6
|
+
export const FormHandler = HttpApiBuilder.group(Api, "server.form", (handlers) => handlers.handle("form.list", Effect.fn(function* () {
|
|
7
|
+
const form = yield* Form.Service;
|
|
8
|
+
return yield* response(form.list());
|
|
9
|
+
})));
|
|
@@ -2,7 +2,12 @@ import { Integration } from "@opencode/core/integration";
|
|
|
2
2
|
import { Effect } from "effect";
|
|
3
3
|
import { HttpApiBuilder, HttpApiSchema } from "effect/unstable/httpapi";
|
|
4
4
|
import { Api } from "../api";
|
|
5
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
IntegrationAttemptNotFoundError,
|
|
7
|
+
IntegrationMethodNotFoundError,
|
|
8
|
+
IntegrationNotFoundError,
|
|
9
|
+
InvalidRequestError
|
|
10
|
+
} from "@opencode/protocol/errors";
|
|
6
11
|
import { response } from "../location";
|
|
7
12
|
import { WellKnown } from "@opencode/core/wellknown";
|
|
8
13
|
const authorize = (effect) => effect.pipe(Effect.mapError((error) => new InvalidRequestError({
|
|
@@ -14,8 +19,13 @@ export const IntegrationHandler = HttpApiBuilder.group(Api, "server.integration"
|
|
|
14
19
|
const service = yield* Integration.Service;
|
|
15
20
|
return yield* response(service.list());
|
|
16
21
|
})).handle("integration.get", Effect.fn(function* (ctx) {
|
|
17
|
-
const
|
|
18
|
-
|
|
22
|
+
const integration = yield* (yield* Integration.Service).get(ctx.params.integrationID);
|
|
23
|
+
if (!integration)
|
|
24
|
+
return yield* new IntegrationNotFoundError({
|
|
25
|
+
integrationID: ctx.params.integrationID,
|
|
26
|
+
message: `Integration not found: ${ctx.params.integrationID}`
|
|
27
|
+
});
|
|
28
|
+
return yield* response(Effect.succeed(integration));
|
|
19
29
|
})).handle("integration.wellknown.add", Effect.fn(function* (ctx) {
|
|
20
30
|
const wellknown = yield* WellKnown.Service, integration = yield* Integration.Service;
|
|
21
31
|
yield* wellknown.add(ctx.payload.url).pipe(Effect.mapError((error) => new InvalidRequestError({ message: error.message, kind: "well_known_discovery" })));
|
|
@@ -23,6 +33,11 @@ export const IntegrationHandler = HttpApiBuilder.group(Api, "server.integration"
|
|
|
23
33
|
return HttpApiSchema.NoContent.make();
|
|
24
34
|
})).handle("integration.connect.key", Effect.fn(function* (ctx) {
|
|
25
35
|
const service = yield* Integration.Service;
|
|
36
|
+
if (!(yield* service.get(ctx.params.integrationID)))
|
|
37
|
+
return yield* new IntegrationNotFoundError({
|
|
38
|
+
integrationID: ctx.params.integrationID,
|
|
39
|
+
message: `Integration not found: ${ctx.params.integrationID}`
|
|
40
|
+
});
|
|
26
41
|
yield* authorize(service.connection.key({
|
|
27
42
|
integrationID: ctx.params.integrationID,
|
|
28
43
|
key: ctx.payload.key,
|
|
@@ -40,19 +55,42 @@ export const IntegrationHandler = HttpApiBuilder.group(Api, "server.integration"
|
|
|
40
55
|
})));
|
|
41
56
|
})).handle("integration.oauth.status", Effect.fn(function* (ctx) {
|
|
42
57
|
const service = yield* Integration.Service;
|
|
58
|
+
if (!(yield* service.get(ctx.params.integrationID)))
|
|
59
|
+
return yield* new IntegrationNotFoundError({
|
|
60
|
+
integrationID: ctx.params.integrationID,
|
|
61
|
+
message: `Integration not found: ${ctx.params.integrationID}`
|
|
62
|
+
});
|
|
43
63
|
return yield* response(service.oauth.status({
|
|
44
64
|
integrationID: ctx.params.integrationID,
|
|
45
65
|
attemptID: ctx.params.attemptID
|
|
46
|
-
}))
|
|
66
|
+
}).pipe(Effect.mapError((error) => new IntegrationAttemptNotFoundError({
|
|
67
|
+
integrationID: error.integrationID,
|
|
68
|
+
attemptID: error.attemptID,
|
|
69
|
+
message: `OAuth attempt not found: ${error.attemptID}`
|
|
70
|
+
}))));
|
|
47
71
|
})).handle("integration.oauth.complete", Effect.fn(function* (ctx) {
|
|
48
|
-
|
|
72
|
+
const service = yield* Integration.Service;
|
|
73
|
+
if (!(yield* service.get(ctx.params.integrationID)))
|
|
74
|
+
return yield* new IntegrationNotFoundError({
|
|
75
|
+
integrationID: ctx.params.integrationID,
|
|
76
|
+
message: `Integration not found: ${ctx.params.integrationID}`
|
|
77
|
+
});
|
|
78
|
+
yield* service.oauth.complete({
|
|
49
79
|
integrationID: ctx.params.integrationID,
|
|
50
80
|
attemptID: ctx.params.attemptID,
|
|
51
81
|
code: ctx.payload.code
|
|
52
|
-
}).pipe(Effect.mapError((error) =>
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
82
|
+
}).pipe(Effect.mapError((error) => {
|
|
83
|
+
if (error._tag === "Integration.AttemptNotFound")
|
|
84
|
+
return new IntegrationAttemptNotFoundError({
|
|
85
|
+
integrationID: error.integrationID,
|
|
86
|
+
attemptID: error.attemptID,
|
|
87
|
+
message: `OAuth attempt not found: ${error.attemptID}`
|
|
88
|
+
});
|
|
89
|
+
return new InvalidRequestError({
|
|
90
|
+
message: error._tag === "Integration.CodeRequired" ? "Authorization code is required" : "Authentication failed",
|
|
91
|
+
kind: error._tag === "Integration.CodeRequired" ? "integration_code_required" : "integration_authorization"
|
|
92
|
+
});
|
|
93
|
+
}));
|
|
56
94
|
return HttpApiSchema.NoContent.make();
|
|
57
95
|
})).handle("integration.oauth.cancel", Effect.fn(function* (ctx) {
|
|
58
96
|
yield* (yield* Integration.Service).oauth.cancel({
|
|
@@ -61,7 +99,18 @@ export const IntegrationHandler = HttpApiBuilder.group(Api, "server.integration"
|
|
|
61
99
|
});
|
|
62
100
|
return HttpApiSchema.NoContent.make();
|
|
63
101
|
})).handle("integration.command.connect", Effect.fn(function* (ctx) {
|
|
64
|
-
const service = yield* Integration.Service;
|
|
102
|
+
const service = yield* Integration.Service, integration = yield* service.get(ctx.params.integrationID);
|
|
103
|
+
if (!integration)
|
|
104
|
+
return yield* new IntegrationNotFoundError({
|
|
105
|
+
integrationID: ctx.params.integrationID,
|
|
106
|
+
message: `Integration not found: ${ctx.params.integrationID}`
|
|
107
|
+
});
|
|
108
|
+
if (!integration.methods.some((method) => method.type === "command" && method.id === ctx.payload.methodID))
|
|
109
|
+
return yield* new IntegrationMethodNotFoundError({
|
|
110
|
+
integrationID: ctx.params.integrationID,
|
|
111
|
+
methodID: ctx.payload.methodID,
|
|
112
|
+
message: `Integration method not found: ${ctx.payload.methodID}`
|
|
113
|
+
});
|
|
65
114
|
return yield* response(authorize(service.command.connect({
|
|
66
115
|
integrationID: ctx.params.integrationID,
|
|
67
116
|
methodID: ctx.payload.methodID,
|
|
@@ -69,10 +118,19 @@ export const IntegrationHandler = HttpApiBuilder.group(Api, "server.integration"
|
|
|
69
118
|
})));
|
|
70
119
|
})).handle("integration.command.status", Effect.fn(function* (ctx) {
|
|
71
120
|
const service = yield* Integration.Service;
|
|
121
|
+
if (!(yield* service.get(ctx.params.integrationID)))
|
|
122
|
+
return yield* new IntegrationNotFoundError({
|
|
123
|
+
integrationID: ctx.params.integrationID,
|
|
124
|
+
message: `Integration not found: ${ctx.params.integrationID}`
|
|
125
|
+
});
|
|
72
126
|
return yield* response(service.command.status({
|
|
73
127
|
integrationID: ctx.params.integrationID,
|
|
74
128
|
attemptID: ctx.params.attemptID
|
|
75
|
-
}))
|
|
129
|
+
}).pipe(Effect.mapError((error) => new IntegrationAttemptNotFoundError({
|
|
130
|
+
integrationID: error.integrationID,
|
|
131
|
+
attemptID: error.attemptID,
|
|
132
|
+
message: `Command attempt not found: ${error.attemptID}`
|
|
133
|
+
}))));
|
|
76
134
|
})).handle("integration.command.cancel", Effect.fn(function* (ctx) {
|
|
77
135
|
yield* (yield* Integration.Service).command.cancel({
|
|
78
136
|
integrationID: ctx.params.integrationID,
|
|
@@ -6,7 +6,6 @@ export const LocationHandler = HttpApiBuilder.group(Api, "server.location", (han
|
|
|
6
6
|
const location = yield* Location.Service;
|
|
7
7
|
return new Location.Info({
|
|
8
8
|
directory: location.directory,
|
|
9
|
-
workspaceID: location.workspaceID,
|
|
10
9
|
project: location.project
|
|
11
10
|
});
|
|
12
11
|
})));
|
package/dist/handlers/model.js
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Model } from "@opencode/core/model";
|
|
2
2
|
import { Effect } from "effect";
|
|
3
3
|
import { HttpApiBuilder } from "effect/unstable/httpapi";
|
|
4
4
|
import { Api } from "../api";
|
|
5
5
|
import { response } from "../location";
|
|
6
6
|
export const ModelHandler = HttpApiBuilder.group(Api, "server.model", (handlers) => Effect.gen(function* () {
|
|
7
7
|
return handlers.handle("model.list", Effect.fn(function* () {
|
|
8
|
-
const
|
|
9
|
-
return yield* response(
|
|
8
|
+
const models = yield* Model.Service;
|
|
9
|
+
return yield* response(models.available());
|
|
10
10
|
})).handle("model.default", Effect.fn(function* () {
|
|
11
|
-
const
|
|
12
|
-
return yield* response(
|
|
11
|
+
const models = yield* Model.Service;
|
|
12
|
+
return yield* response(models.default());
|
|
13
13
|
}));
|
|
14
14
|
}));
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { Instance } from "@opencode/core/instance/service";
|
|
2
2
|
import { PermissionSaved } from "@opencode/core/permission/saved";
|
|
3
3
|
import { Session } from "@opencode/core/session";
|
|
4
|
-
export declare const PermissionHandler: import("effect/Layer").Layer<import("effect/unstable/httpapi/HttpApiGroup").Service<"server", "server.permission">, never, import("@opencode/protocol/middleware/schema-error").SchemaErrorMiddleware | import("@opencode/protocol/middleware/authorization").Authorization |
|
|
4
|
+
export declare const PermissionHandler: import("effect/Layer").Layer<import("effect/unstable/httpapi/HttpApiGroup").Service<"server", "server.permission">, never, Session.Service | Instance.Service | import("../middleware/session-location").SessionLocationMiddleware | (import("@opencode/protocol/middleware/schema-error").SchemaErrorMiddleware | import("@opencode/protocol/middleware/authorization").Authorization | import("../location").LocationMiddleware | import("effect/unstable/http/HttpRouter").Request<"Requires", PermissionSaved.Service>)>;
|
|
@@ -41,10 +41,7 @@ export const PermissionHandler = HttpApiBuilder.group(Api, "server.permission",
|
|
|
41
41
|
})).handle("session.permission.get", Effect.fn(function* (ctx) {
|
|
42
42
|
return { data: (yield* requireOwnedRequest(ctx.params.sessionID, ctx.params.requestID)).request };
|
|
43
43
|
})).handle("session.permission.reply", Effect.fn(function* (ctx) {
|
|
44
|
-
yield* (yield* requireOwnedRequest(ctx.params.sessionID, ctx.params.requestID)).permission.reply({ requestID: ctx.params.requestID, reply: ctx.payload.
|
|
45
|
-
return HttpApiSchema.NoContent.make();
|
|
46
|
-
})).handle("session.permission.rules", Effect.fn(function* (ctx) {
|
|
47
|
-
yield* sessions.setPermissions({ sessionID: ctx.params.sessionID, permissions: ctx.payload.permissions }).pipe(Effect.catchTag("Session.NotFoundError", missingSession));
|
|
44
|
+
yield* (yield* requireOwnedRequest(ctx.params.sessionID, ctx.params.requestID)).permission.reply({ requestID: ctx.params.requestID, reply: ctx.payload.decision, message: ctx.payload.message }).pipe(Effect.catchTag("Permission.NotFoundError", () => missingRequest(ctx.params.requestID)));
|
|
48
45
|
return HttpApiSchema.NoContent.make();
|
|
49
46
|
})).handle("permission.saved.list", Effect.fn(function* (ctx) {
|
|
50
47
|
const location = yield* Location.Service;
|
package/dist/handlers/plugin.js
CHANGED
|
@@ -7,10 +7,8 @@ import { Api } from "../api";
|
|
|
7
7
|
import { response } from "../location";
|
|
8
8
|
export const PluginHandler = HttpApiBuilder.group(Api, "server.plugin", (handlers) => handlers.handle("plugin.list", () => Effect.gen(function* () {
|
|
9
9
|
return yield* response(Plugin.Service.use((plugin) => plugin.list()));
|
|
10
|
-
})).handle("plugin.
|
|
11
|
-
const
|
|
12
|
-
yield* plugins.awaitActivation;
|
|
13
|
-
const inventory = yield* plugins.list(), targets = [
|
|
10
|
+
})).handle("plugin.check", (ctx) => Effect.gen(function* () {
|
|
11
|
+
const inventory = yield* (yield* Plugin.Service).list(), targets = [
|
|
14
12
|
...new Set(inventory.flatMap((plugin) => plugin.source.type === "package" ? [plugin.source.target] : []))
|
|
15
13
|
].filter((target) => ctx.payload.target === void 0 || target === ctx.payload.target);
|
|
16
14
|
if (ctx.payload.target !== void 0 && !targets.length)
|
|
@@ -34,9 +32,7 @@ export const PluginHandler = HttpApiBuilder.group(Api, "server.plugin", (handler
|
|
|
34
32
|
};
|
|
35
33
|
})));
|
|
36
34
|
})).handle("plugin.update", (ctx) => Effect.gen(function* () {
|
|
37
|
-
const plugins = yield* Plugin.Service;
|
|
38
|
-
yield* plugins.awaitActivation;
|
|
39
|
-
const inventory = new Set((yield* plugins.list()).flatMap((plugin) => plugin.source.type === "package" ? [plugin.source.target] : [])), unknown = ctx.payload.targets.filter((target) => !inventory.has(target));
|
|
35
|
+
const plugins = yield* Plugin.Service, inventory = new Set((yield* plugins.list()).flatMap((plugin) => plugin.source.type === "package" ? [plugin.source.target] : [])), unknown = ctx.payload.targets.filter((target) => !inventory.has(target));
|
|
40
36
|
if (unknown.length)
|
|
41
37
|
return yield* new InvalidRequestError({
|
|
42
38
|
message: `Plugin packages are not in the current server inventory: ${unknown.join(", ")}`,
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { Project } from "@opencode/core/project";
|
|
2
|
-
export declare const ProjectHandler: import("effect/Layer").Layer<import("effect/unstable/httpapi/HttpApiGroup").Service<"server", "server.project">, never, import("
|
|
2
|
+
export declare const ProjectHandler: import("effect/Layer").Layer<import("effect/unstable/httpapi/HttpApiGroup").Service<"server", "server.project">, never, import("@opencode/protocol/middleware/schema-error").SchemaErrorMiddleware | import("@opencode/protocol/middleware/authorization").Authorization | import("../location").LocationMiddleware | import("effect/unstable/http/HttpRouter").Request<"Requires", Project.Service>>;
|
package/dist/handlers/project.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { Location } from "@opencode/core/location";
|
|
2
1
|
import { Project } from "@opencode/core/project";
|
|
3
2
|
import { Effect } from "effect";
|
|
4
3
|
import { HttpApiBuilder } from "effect/unstable/httpapi";
|
|
@@ -7,8 +6,4 @@ import { ProjectNotFoundError } from "@opencode/protocol/errors";
|
|
|
7
6
|
export const ProjectHandler = HttpApiBuilder.group(Api, "server.project", (handlers) => handlers.handle("project.list", () => Project.Service.use((project) => project.list())).handle("project.update", (ctx) => Project.Service.use((project) => project.update({ ...ctx.payload, projectID: ctx.params.projectID }).pipe(Effect.mapError(() => new ProjectNotFoundError({
|
|
8
7
|
projectID: ctx.params.projectID,
|
|
9
8
|
message: `Project not found: ${ctx.params.projectID}`
|
|
10
|
-
})))))
|
|
11
|
-
id: location.project.id,
|
|
12
|
-
directory: location.project.directory,
|
|
13
|
-
canonical: location.project.canonical
|
|
14
|
-
}))));
|
|
9
|
+
}))))));
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Provider } from "@opencode/core/provider";
|
|
2
2
|
import { ProviderNotFoundError } from "@opencode/protocol/errors";
|
|
3
3
|
import { Effect } from "effect";
|
|
4
4
|
import { HttpApiBuilder } from "effect/unstable/httpapi";
|
|
@@ -6,10 +6,10 @@ import { Api } from "../api";
|
|
|
6
6
|
import { response } from "../location";
|
|
7
7
|
export const ProviderHandler = HttpApiBuilder.group(Api, "server.provider", (handlers) => Effect.gen(function* () {
|
|
8
8
|
return handlers.handle("provider.list", Effect.fn(function* () {
|
|
9
|
-
const
|
|
10
|
-
return yield* response(
|
|
9
|
+
const providers = yield* Provider.Service;
|
|
10
|
+
return yield* response(providers.available());
|
|
11
11
|
})).handle("provider.get", Effect.fn(function* (ctx) {
|
|
12
|
-
const provider = yield* (yield*
|
|
12
|
+
const provider = yield* (yield* Provider.Service).get(ctx.params.providerID);
|
|
13
13
|
if (!provider)
|
|
14
14
|
return yield* new ProviderNotFoundError({
|
|
15
15
|
providerID: ctx.params.providerID,
|
package/dist/handlers/server.js
CHANGED
|
@@ -2,6 +2,11 @@ import { Effect } from "effect";
|
|
|
2
2
|
import { HttpApiBuilder } from "effect/unstable/httpapi";
|
|
3
3
|
import { Api } from "../api";
|
|
4
4
|
import { ServerInfo } from "../server-info";
|
|
5
|
-
export const ServerHandler = HttpApiBuilder.group(Api, "server.server", (handlers) => handlers.handle("server.
|
|
6
|
-
|
|
5
|
+
export const ServerHandler = HttpApiBuilder.group(Api, "server.server", (handlers) => handlers.handle("server.status", () => Effect.gen(function* () {
|
|
6
|
+
const info = yield* ServerInfo.Service;
|
|
7
|
+
return {
|
|
8
|
+
version: info.app.version ?? "unknown",
|
|
9
|
+
pid: process.pid ?? 0,
|
|
10
|
+
urls: info.urls()
|
|
11
|
+
};
|
|
7
12
|
})));
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { Session } from "@opencode/core/session";
|
|
2
2
|
import { SessionTransfer } from "@opencode/core/session/transfer";
|
|
3
|
-
export declare const SessionHandler: import("effect/Layer").Layer<import("effect/unstable/httpapi/HttpApiGroup").Service<"server", "server.session">, never, Session.Service | import("../middleware/session-location").SessionLocationMiddleware | SessionTransfer.Service | import("effect/unstable/http/HttpRouter").Request<"Requires", import("@opencode/core/database/database").Service> | (import("@opencode/protocol/middleware/schema-error").SchemaErrorMiddleware | import("@opencode/protocol/middleware/authorization").Authorization)>;
|
|
3
|
+
export declare const SessionHandler: import("effect/Layer").Layer<import("effect/unstable/httpapi/HttpApiGroup").Service<"server", "server.session">, never, Session.Service | import("../middleware/session-location").SessionLocationMiddleware | SessionTransfer.Service | import("effect/unstable/http/HttpRouter").Request<"Requires", import("@opencode/core/database/database").Service> | (import("@opencode/protocol/middleware/schema-error").SchemaErrorMiddleware | import("@opencode/protocol/middleware/authorization").Authorization | import("../middleware/form-location").FormLocationMiddleware)>;
|
package/dist/handlers/session.js
CHANGED
|
@@ -3,6 +3,7 @@ import { SessionStats } from "@opencode/core/session/stats";
|
|
|
3
3
|
import { SessionTitle } from "@opencode/core/session/title";
|
|
4
4
|
import { SessionTransfer } from "@opencode/core/session/transfer";
|
|
5
5
|
import { InstructionEntry } from "@opencode/core/session/instruction-entry";
|
|
6
|
+
import { Form } from "@opencode/core/form";
|
|
6
7
|
import { DateTime, Effect, Stream } from "effect";
|
|
7
8
|
import { HttpApiBuilder, HttpApiSchema } from "effect/unstable/httpapi";
|
|
8
9
|
import { Api } from "../api";
|
|
@@ -11,6 +12,9 @@ import {
|
|
|
11
12
|
ConflictError,
|
|
12
13
|
CommandExecutionError,
|
|
13
14
|
CommandNotFoundError,
|
|
15
|
+
FormAlreadySettledError,
|
|
16
|
+
FormInvalidAnswerError,
|
|
17
|
+
FormNotFoundError,
|
|
14
18
|
InvalidRequestError,
|
|
15
19
|
InvalidCursorError,
|
|
16
20
|
MessageNotFoundError,
|
|
@@ -21,15 +25,22 @@ import {
|
|
|
21
25
|
import { AbsolutePath } from "@opencode/core/schema";
|
|
22
26
|
import { failedMessageDecode, failedSnapshot, missingMessage, missingSession } from "./session-error";
|
|
23
27
|
const DefaultSessionsLimit = 50;
|
|
28
|
+
function missingForm(id) {
|
|
29
|
+
return new FormNotFoundError({ id, message: `Form not found: ${id}` });
|
|
30
|
+
}
|
|
24
31
|
export const SessionHandler = HttpApiBuilder.group(Api, "server.session", (handlers) => Effect.gen(function* () {
|
|
25
|
-
const session = yield* Session.Service, transfer = yield* SessionTransfer.Service,
|
|
32
|
+
const session = yield* Session.Service, transfer = yield* SessionTransfer.Service, requireOwnedForm = Effect.fnUntraced(function* (sessionID, formID) {
|
|
33
|
+
const form = yield* Form.Service, info = yield* form.get(formID).pipe(Effect.catchTag("Form.NotFoundError", () => missingForm(formID)));
|
|
34
|
+
if (info.sessionID !== sessionID)
|
|
35
|
+
return yield* missingForm(formID);
|
|
36
|
+
return { form, info };
|
|
37
|
+
}), busySession = (error) => new SessionBusyError({
|
|
26
38
|
sessionID: error.sessionID,
|
|
27
39
|
message: `Session is busy: ${error.sessionID}`
|
|
28
40
|
}), pendingMutation = (effect, conflict) => effect.pipe(Effect.catchTag("Session.NotFoundError", missingSession), Effect.catchTag("Session.InboxConflictError", (error) => new ConflictError({ resource: error.inboxID, message: `${conflict}: ${error.inboxID}` })), Effect.as(HttpApiSchema.NoContent.make()));
|
|
29
41
|
return handlers.handle("session.list", Effect.fn(function* (ctx) {
|
|
30
42
|
const query = ctx.query.cursor !== void 0 ? yield* SessionsCursor.parse(ctx.query.cursor).pipe(Effect.mapError(() => new InvalidCursorError({ message: "Invalid cursor" }))) : ctx.query, sessions = (yield* session.list({
|
|
31
43
|
...query,
|
|
32
|
-
workspaceID: query.workspace,
|
|
33
44
|
limit: ctx.query.limit ?? DefaultSessionsLimit
|
|
34
45
|
})).data, first = sessions[0], last = sessions.at(-1);
|
|
35
46
|
return {
|
|
@@ -104,7 +115,7 @@ export const SessionHandler = HttpApiBuilder.group(Api, "server.session", (handl
|
|
|
104
115
|
data: yield* session.get(ctx.params.sessionID).pipe(Effect.catchTag("Session.NotFoundError", missingSession))
|
|
105
116
|
};
|
|
106
117
|
})).handle("session.view", Effect.fn(function* (ctx) {
|
|
107
|
-
yield* session.view({ sessionID: ctx.params.sessionID, idle: ctx.payload.idle }).pipe(Effect.catchTag("Session.NotFoundError", missingSession));
|
|
118
|
+
yield* session.view({ sessionID: ctx.params.sessionID, idle: DateTime.toEpochMillis(ctx.payload.idle) }).pipe(Effect.catchTag("Session.NotFoundError", missingSession));
|
|
108
119
|
return HttpApiSchema.NoContent.make();
|
|
109
120
|
})).handle("session.remove", Effect.fn(function* (ctx) {
|
|
110
121
|
yield* session.remove(ctx.params.sessionID).pipe(Effect.catchTag("Session.NotFoundError", missingSession));
|
|
@@ -114,7 +125,7 @@ export const SessionHandler = HttpApiBuilder.group(Api, "server.session", (handl
|
|
|
114
125
|
return HttpApiSchema.NoContent.make();
|
|
115
126
|
})).handle("session.fork", Effect.fn(function* (ctx) {
|
|
116
127
|
return {
|
|
117
|
-
data: yield* session.fork({ sessionID: ctx.params.sessionID,
|
|
128
|
+
data: yield* session.fork({ sessionID: ctx.params.sessionID, before: ctx.payload.before }).pipe(Effect.catchTag("Session.NotFoundError", missingSession), Effect.catchTag("Session.MessageNotFoundError", missingMessage), Effect.catchTag("Session.ForkEmptyError", (error) => new InvalidRequestError({ message: error.message, kind: "empty_session" })))
|
|
118
129
|
};
|
|
119
130
|
})).handle("session.switchAgent", Effect.fn(function* (ctx) {
|
|
120
131
|
yield* session.switchAgent({ sessionID: ctx.params.sessionID, agent: ctx.payload.agent }).pipe(Effect.catchTag("Session.NotFoundError", missingSession));
|
|
@@ -122,18 +133,20 @@ export const SessionHandler = HttpApiBuilder.group(Api, "server.session", (handl
|
|
|
122
133
|
})).handle("session.switchModel", Effect.fn(function* (ctx) {
|
|
123
134
|
yield* session.switchModel({ sessionID: ctx.params.sessionID, model: ctx.payload.model }).pipe(Effect.catchTag("Session.NotFoundError", missingSession));
|
|
124
135
|
return HttpApiSchema.NoContent.make();
|
|
125
|
-
})).handle("session.
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
136
|
+
})).handle("session.update", Effect.fn(function* (ctx) {
|
|
137
|
+
yield* session.get(ctx.params.sessionID).pipe(Effect.catchTag("Session.NotFoundError", missingSession));
|
|
138
|
+
if (ctx.payload.title !== void 0)
|
|
139
|
+
if (ctx.payload.title)
|
|
140
|
+
yield* session.rename({ sessionID: ctx.params.sessionID, title: ctx.payload.title }).pipe(Effect.catchTag("Session.NotFoundError", missingSession));
|
|
141
|
+
else
|
|
142
|
+
yield* (yield* SessionTitle.Service).generate(ctx.params.sessionID);
|
|
143
|
+
if (ctx.payload.permissions !== void 0)
|
|
144
|
+
yield* session.setPermissions({ sessionID: ctx.params.sessionID, permissions: ctx.payload.permissions }).pipe(Effect.catchTag("Session.NotFoundError", missingSession));
|
|
131
145
|
return HttpApiSchema.NoContent.make();
|
|
132
146
|
})).handle("session.move", Effect.fn(function* (ctx) {
|
|
133
147
|
yield* session.move({
|
|
134
148
|
sessionID: ctx.params.sessionID,
|
|
135
149
|
directory: ctx.payload.directory,
|
|
136
|
-
workspaceID: ctx.payload.workspaceID,
|
|
137
150
|
delivery: ctx.payload.delivery
|
|
138
151
|
}).pipe(Effect.catchTag("Session.NotFoundError", missingSession), Effect.catchTag("Session.DestinationNotFoundError", (error) => Effect.fail(new InvalidRequestError({ message: `Directory does not exist: ${error.directory}` }))), Effect.catchTag("Session.DestinationNotDirectoryError", (error) => Effect.fail(new InvalidRequestError({ message: `Not a directory: ${error.directory}` }))), Effect.catchTag("Session.DestinationUnavailableError", (error) => Effect.fail(new InvalidRequestError({ message: `Directory is unavailable: ${error.directory}` }))));
|
|
139
152
|
return HttpApiSchema.NoContent.make();
|
|
@@ -157,7 +170,7 @@ export const SessionHandler = HttpApiBuilder.group(Api, "server.session", (handl
|
|
|
157
170
|
})).handle("session.command", Effect.fn(function* (ctx) {
|
|
158
171
|
yield* session.command({
|
|
159
172
|
sessionID: ctx.params.sessionID,
|
|
160
|
-
command: ctx.payload.
|
|
173
|
+
command: ctx.payload.name,
|
|
161
174
|
text: ctx.payload.text,
|
|
162
175
|
files: ctx.payload.files,
|
|
163
176
|
agents: ctx.payload.agents,
|
|
@@ -174,8 +187,7 @@ export const SessionHandler = HttpApiBuilder.group(Api, "server.session", (handl
|
|
|
174
187
|
})).handle("session.skill", Effect.fn(function* (ctx) {
|
|
175
188
|
yield* session.skill({
|
|
176
189
|
sessionID: ctx.params.sessionID,
|
|
177
|
-
|
|
178
|
-
skill: ctx.payload.skill,
|
|
190
|
+
skill: ctx.payload.id,
|
|
179
191
|
resume: ctx.payload.resume
|
|
180
192
|
}).pipe(Effect.catchTag("Session.NotFoundError", missingSession), Effect.catchTag("Session.SkillNotFoundError", (error) => Effect.fail(new SkillNotFoundError({ skill: error.skill, message: `Skill not found: ${error.skill}` }))));
|
|
181
193
|
return HttpApiSchema.NoContent.make();
|
|
@@ -235,11 +247,10 @@ export const SessionHandler = HttpApiBuilder.group(Api, "server.session", (handl
|
|
|
235
247
|
data: yield* session.inbox(ctx.params.sessionID).pipe(Effect.catchTag("Session.NotFoundError", missingSession))
|
|
236
248
|
};
|
|
237
249
|
})).handle("session.inbox.cancel", Effect.fn(function* (ctx) {
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
return yield* pendingMutation(session.queueInbox({ sessionID: ctx.params.sessionID, inboxID: ctx.params.inboxID }), "Pending input is no longer a steer");
|
|
250
|
+
yield* session.cancelInbox({ sessionID: ctx.params.sessionID, inboxID: ctx.params.inboxID }).pipe(Effect.catchTag("Session.NotFoundError", missingSession), Effect.catchTag("Session.InboxConflictError", () => Effect.void));
|
|
251
|
+
return HttpApiSchema.NoContent.make();
|
|
252
|
+
})).handle("session.inbox.update", Effect.fn(function* (ctx) {
|
|
253
|
+
return yield* pendingMutation(ctx.payload.delivery === "steer" ? session.steerInbox({ sessionID: ctx.params.sessionID, inboxID: ctx.params.inboxID }) : session.queueInbox({ sessionID: ctx.params.sessionID, inboxID: ctx.params.inboxID }), `Pending input cannot change to ${ctx.payload.delivery}`);
|
|
243
254
|
})).handle("session.instructions.entry.list", Effect.fn(function* (ctx) {
|
|
244
255
|
return { data: yield* (yield* InstructionEntry.Service).list(ctx.params.sessionID) };
|
|
245
256
|
})).handle("session.instructions.entry.put", Effect.fn(function* (ctx) {
|
|
@@ -254,7 +265,7 @@ export const SessionHandler = HttpApiBuilder.group(Api, "server.session", (handl
|
|
|
254
265
|
yield* session.get(ctx.params.sessionID).pipe(Effect.catchTag("Session.NotFoundError", missingSession));
|
|
255
266
|
return session.log({ sessionID: ctx.params.sessionID, after: ctx.query.after, follow: ctx.query.follow }).pipe(Stream.orDie);
|
|
256
267
|
})).handle("session.interrupt", Effect.fn(function* (ctx) {
|
|
257
|
-
return { interrupted: yield* session.interrupt(ctx.params.sessionID, {
|
|
268
|
+
return { interrupted: yield* session.interrupt(ctx.params.sessionID, { resume: ctx.query.resume }) };
|
|
258
269
|
})).handle("session.background", Effect.fn(function* (ctx) {
|
|
259
270
|
yield* session.background(ctx.params.sessionID).pipe(Effect.catchTag("Session.NotFoundError", missingSession));
|
|
260
271
|
return HttpApiSchema.NoContent.make();
|
|
@@ -268,5 +279,34 @@ export const SessionHandler = HttpApiBuilder.group(Api, "server.session", (handl
|
|
|
268
279
|
messageID: ctx.params.messageID,
|
|
269
280
|
message: `Message not found: ${ctx.params.messageID}`
|
|
270
281
|
});
|
|
282
|
+
})).handle("session.form.list", Effect.fn(function* (ctx) {
|
|
283
|
+
return { data: yield* (yield* Form.Service).list({ sessionID: ctx.params.sessionID }) };
|
|
284
|
+
})).handle("session.form.create", Effect.fn(function* (ctx) {
|
|
285
|
+
return { data: yield* (yield* Form.Service).create({
|
|
286
|
+
id: ctx.payload.id,
|
|
287
|
+
sessionID: ctx.params.sessionID,
|
|
288
|
+
title: ctx.payload.title,
|
|
289
|
+
metadata: ctx.payload.metadata,
|
|
290
|
+
fields: ctx.payload.fields
|
|
291
|
+
}).pipe(Effect.catchTags({
|
|
292
|
+
"Form.AlreadyExistsError": (error) => new ConflictError({ resource: error.id, message: error.message }),
|
|
293
|
+
"Form.InvalidFormError": (error) => new InvalidRequestError({ message: error.message, field: "fields" })
|
|
294
|
+
})) };
|
|
295
|
+
})).handle("session.form.get", Effect.fn(function* (ctx) {
|
|
296
|
+
const owned = yield* requireOwnedForm(ctx.params.sessionID, ctx.params.formID), state = yield* owned.form.state(ctx.params.formID).pipe(Effect.catchTag("Form.NotFoundError", () => missingForm(ctx.params.formID)));
|
|
297
|
+
return { data: { ...owned.info, state } };
|
|
298
|
+
})).handle("session.form.reply", Effect.fn(function* (ctx) {
|
|
299
|
+
yield* (yield* requireOwnedForm(ctx.params.sessionID, ctx.params.formID)).form.reply({ id: ctx.params.formID, answer: ctx.payload.answer }).pipe(Effect.catchTags({
|
|
300
|
+
"Form.AlreadySettledError": (error) => new FormAlreadySettledError({ id: error.id, message: error.message }),
|
|
301
|
+
"Form.InvalidAnswerError": (error) => new FormInvalidAnswerError({ id: error.id, message: error.message }),
|
|
302
|
+
"Form.NotFoundError": () => missingForm(ctx.params.formID)
|
|
303
|
+
}));
|
|
304
|
+
return HttpApiSchema.NoContent.make();
|
|
305
|
+
})).handle("session.form.cancel", Effect.fn(function* (ctx) {
|
|
306
|
+
yield* (yield* requireOwnedForm(ctx.params.sessionID, ctx.params.formID)).form.cancel(ctx.params.formID).pipe(Effect.catchTags({
|
|
307
|
+
"Form.AlreadySettledError": (error) => new FormAlreadySettledError({ id: error.id, message: error.message }),
|
|
308
|
+
"Form.NotFoundError": () => missingForm(ctx.params.formID)
|
|
309
|
+
}));
|
|
310
|
+
return HttpApiSchema.NoContent.make();
|
|
271
311
|
}));
|
|
272
312
|
}));
|
package/dist/handlers/shell.js
CHANGED
|
@@ -15,14 +15,11 @@ export const ShellHandler = HttpApiBuilder.group(Api, "server.shell", (handlers)
|
|
|
15
15
|
})).handle("shell.get", Effect.fn(function* (ctx) {
|
|
16
16
|
const shell = yield* Shell.Service;
|
|
17
17
|
return yield* response(shell.get(ctx.params.id).pipe(Effect.catchTag("Shell.NotFoundError", () => new ShellNotFoundError({ id: ctx.params.id, message: `Shell command not found: ${ctx.params.id}` }))));
|
|
18
|
-
})).handle("shell.timeout", Effect.fn(function* (ctx) {
|
|
19
|
-
const shell = yield* Shell.Service;
|
|
20
|
-
return yield* response(shell.timeout(ctx.params.id, ctx.payload.timeout).pipe(Effect.catchTag("Shell.NotFoundError", () => new ShellNotFoundError({ id: ctx.params.id, message: `Shell command not found: ${ctx.params.id}` }))));
|
|
21
18
|
})).handle("shell.output", Effect.fn(function* (ctx) {
|
|
22
19
|
const shell = yield* Shell.Service;
|
|
23
20
|
return yield* response(shell.output(ctx.params.id, { cursor: ctx.query.cursor, limit: ctx.query.limit }).pipe(Effect.catchTag("Shell.NotFoundError", () => new ShellNotFoundError({ id: ctx.params.id, message: `Shell command not found: ${ctx.params.id}` }))));
|
|
24
21
|
})).handle("shell.remove", Effect.fn(function* (ctx) {
|
|
25
|
-
yield* (yield* Shell.Service).remove(ctx.params.id).pipe(Effect.catchTag("Shell.NotFoundError", () =>
|
|
22
|
+
yield* (yield* Shell.Service).remove(ctx.params.id).pipe(Effect.catchTag("Shell.NotFoundError", () => Effect.void));
|
|
26
23
|
return HttpApiSchema.NoContent.make();
|
|
27
24
|
}));
|
|
28
25
|
}));
|
package/dist/handlers/vcs.js
CHANGED
|
@@ -11,7 +11,7 @@ export const VcsHandler = HttpApiBuilder.group(Api, "server.vcs", (handlers) =>
|
|
|
11
11
|
return yield* (yield* Vcs.Service).base().pipe(Effect.mapError((error) => new ServiceUnavailableError({ service: "vcs", message: error.message })));
|
|
12
12
|
}))).handle("vcs.status", () => response(Effect.gen(function* () {
|
|
13
13
|
return yield* (yield* Vcs.Service).status();
|
|
14
|
-
}))).handle("vcs.
|
|
14
|
+
}))).handle("vcs.branch.list", (ctx) => response(Effect.gen(function* () {
|
|
15
15
|
return yield* (yield* Vcs.Service).branches({ search: ctx.query.search, limit: Math.min(ctx.query.limit ?? 50, 100) });
|
|
16
16
|
}))).handle("vcs.diff", (ctx) => response(Effect.gen(function* () {
|
|
17
17
|
return yield* (yield* Vcs.Service).diff(ctx.query.mode, { context: ctx.query.context, base: ctx.query.base }).pipe(Effect.mapError((error) => new ServiceUnavailableError({ service: "vcs", message: error.message })));
|
|
@@ -1 +1,2 @@
|
|
|
1
|
-
|
|
1
|
+
import { Worktree } from "@opencode/core/worktree";
|
|
2
|
+
export declare const WorktreeHandler: import("effect/Layer").Layer<import("effect/unstable/httpapi/HttpApiGroup").Service<"server", "server.worktree">, never, import("@opencode/protocol/middleware/schema-error").SchemaErrorMiddleware | import("@opencode/protocol/middleware/authorization").Authorization | Worktree.Service>;
|
|
@@ -1,20 +1,17 @@
|
|
|
1
1
|
import { Git } from "@opencode/core/git";
|
|
2
2
|
import { Worktree } from "@opencode/core/worktree";
|
|
3
|
-
import {
|
|
3
|
+
import { Project } from "@opencode/core/project";
|
|
4
|
+
import { ProjectNotFoundError } from "@opencode/protocol/errors";
|
|
4
5
|
import { WorktreeError } from "@opencode/protocol/groups/worktree";
|
|
5
6
|
import { Effect } from "effect";
|
|
6
7
|
import { HttpApiBuilder, HttpApiSchema } from "effect/unstable/httpapi";
|
|
7
8
|
import { Api } from "../api";
|
|
8
|
-
export const WorktreeHandler = HttpApiBuilder.group(Api, "server.worktree", (handlers) =>
|
|
9
|
-
|
|
10
|
-
return Effect.
|
|
11
|
-
|
|
12
|
-
yield* plugins.awaitActivation;
|
|
13
|
-
return yield* action(worktrees);
|
|
14
|
-
}).pipe(badRequest);
|
|
15
|
-
}
|
|
9
|
+
export const WorktreeHandler = HttpApiBuilder.group(Api, "server.worktree", (handlers) => Effect.gen(function* () {
|
|
10
|
+
const worktrees = yield* Worktree.Service;
|
|
11
|
+
return handlers.handle("worktree.list", (ctx) => worktrees.list(ctx.query).pipe(Effect.catchTag("Project.NotFoundError", missingProject))).handle("worktree.create", (ctx) => worktrees.create(ctx.payload).pipe(badRequest)).handle("worktree.remove", (ctx) => worktrees.remove(ctx.payload).pipe(badRequest, Effect.as(HttpApiSchema.NoContent.make()))).handle("worktree.refresh", (ctx) => worktrees.refresh(ctx.payload).pipe(badRequest, Effect.as(HttpApiSchema.NoContent.make())));
|
|
12
|
+
}));
|
|
16
13
|
function badRequest(effect) {
|
|
17
|
-
return effect.pipe(Effect.mapError((error) => new WorktreeError({
|
|
14
|
+
return effect.pipe(Effect.catchTag("Project.NotFoundError", missingProject), Effect.mapError((error) => error instanceof ProjectNotFoundError ? error : new WorktreeError({
|
|
18
15
|
name: "WorktreeError",
|
|
19
16
|
data: {
|
|
20
17
|
message: message(error),
|
|
@@ -22,6 +19,9 @@ function badRequest(effect) {
|
|
|
22
19
|
}
|
|
23
20
|
})));
|
|
24
21
|
}
|
|
22
|
+
function missingProject(error) {
|
|
23
|
+
return Effect.fail(new ProjectNotFoundError({ projectID: error.projectID, message: `Project not found: ${error.projectID}` }));
|
|
24
|
+
}
|
|
25
25
|
function message(error) {
|
|
26
26
|
if (error instanceof Worktree.SourceDirectoryNotFoundError)
|
|
27
27
|
return error.directory ? `Worktree source not found: ${error.directory}` : `Worktree source not found for project: ${error.projectID}`;
|
|
@@ -33,7 +33,5 @@ function message(error) {
|
|
|
33
33
|
return `Invalid worktree directory: ${error.directory}`;
|
|
34
34
|
if (error instanceof Worktree.StrategyUnavailableError)
|
|
35
35
|
return `Worktree strategy unavailable: ${error.strategy}`;
|
|
36
|
-
if (error instanceof Worktree.UnsupportedLocationError)
|
|
37
|
-
return "Worktree operations only support local locations";
|
|
38
36
|
return error.message;
|
|
39
37
|
}
|
package/dist/handlers.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { Layer } from "effect";
|
|
2
|
-
export declare const handlers: Layer.Layer<import("effect/unstable/httpapi/HttpApiGroup").Service<"server", "server.generate"> | import("effect/unstable/httpapi/HttpApiGroup").Service<"server", "server.message"> | import("effect/unstable/httpapi/HttpApiGroup").Service<"server", "server.model"> | import("effect/unstable/httpapi/HttpApiGroup").Service<"server", "server.provider"> | import("effect/unstable/httpapi/HttpApiGroup").Service<"server", "server.session"> | import("effect/unstable/httpapi/HttpApiGroup").Service<"server", "server.permission"> | import("effect/unstable/httpapi/HttpApiGroup").Service<"server", "server.fs"> | import("effect/unstable/httpapi/HttpApiGroup").Service<"server", "server.form"> | import("effect/unstable/httpapi/HttpApiGroup").Service<"server", "server.command"> | import("effect/unstable/httpapi/HttpApiGroup").Service<"server", "server.skill"> | import("effect/unstable/httpapi/HttpApiGroup").Service<"server", "server.rpc"> | import("effect/unstable/httpapi/HttpApiGroup").Service<"server", "server.event"> | import("effect/unstable/httpapi/HttpApiGroup").Service<"server", "server.agent"> | import("effect/unstable/httpapi/HttpApiGroup").Service<"server", "server.plugin"> | import("effect/unstable/httpapi/HttpApiGroup").Service<"server", "server.
|
|
2
|
+
export declare const handlers: Layer.Layer<import("effect/unstable/httpapi/HttpApiGroup").Service<"server", "server.generate"> | import("effect/unstable/httpapi/HttpApiGroup").Service<"server", "server.message"> | import("effect/unstable/httpapi/HttpApiGroup").Service<"server", "server.model"> | import("effect/unstable/httpapi/HttpApiGroup").Service<"server", "server.provider"> | import("effect/unstable/httpapi/HttpApiGroup").Service<"server", "server.session"> | import("effect/unstable/httpapi/HttpApiGroup").Service<"server", "server.permission"> | import("effect/unstable/httpapi/HttpApiGroup").Service<"server", "server.fs"> | import("effect/unstable/httpapi/HttpApiGroup").Service<"server", "server.form"> | import("effect/unstable/httpapi/HttpApiGroup").Service<"server", "server.command"> | import("effect/unstable/httpapi/HttpApiGroup").Service<"server", "server.skill"> | import("effect/unstable/httpapi/HttpApiGroup").Service<"server", "server.rpc"> | import("effect/unstable/httpapi/HttpApiGroup").Service<"server", "server.event"> | import("effect/unstable/httpapi/HttpApiGroup").Service<"server", "server.agent"> | import("effect/unstable/httpapi/HttpApiGroup").Service<"server", "server.plugin"> | import("effect/unstable/httpapi/HttpApiGroup").Service<"server", "server.server"> | import("effect/unstable/httpapi/HttpApiGroup").Service<"server", "server.debug"> | import("effect/unstable/httpapi/HttpApiGroup").Service<"server", "server.pty"> | import("effect/unstable/httpapi/HttpApiGroup").Service<"server", "server.experimental"> | import("effect/unstable/httpapi/HttpApiGroup").Service<"server", "server.shell"> | import("effect/unstable/httpapi/HttpApiGroup").Service<"server", "server.reference"> | import("effect/unstable/httpapi/HttpApiGroup").Service<"server", "server.location"> | import("effect/unstable/httpapi/HttpApiGroup").Service<"server", "server.integration"> | import("effect/unstable/httpapi/HttpApiGroup").Service<"server", "server.websearch"> | import("effect/unstable/httpapi/HttpApiGroup").Service<"server", "server.mcp"> | import("effect/unstable/httpapi/HttpApiGroup").Service<"server", "server.credential"> | import("effect/unstable/httpapi/HttpApiGroup").Service<"server", "server.project"> | import("effect/unstable/httpapi/HttpApiGroup").Service<"server", "server.worktree"> | import("effect/unstable/httpapi/HttpApiGroup").Service<"server", "server.vcs"> | import("effect/unstable/httpapi/HttpApiGroup").Service<"server", "server.migration"> | import("effect/unstable/httpapi/HttpApiGroup").Service<"server", "server.config">, never, import("@opencode/protocol/middleware/schema-error").SchemaErrorMiddleware | import("@opencode/protocol/middleware/authorization").Authorization | import("@opencode/util/global").Service | import("@opencode/core/bus").Service | import("@opencode/core/persistent-pty/index").Service | import("@opencode/core/location-service-map").Service | import("@opencode/core/session").Service | import("@opencode/core/instance").Service | import("@opencode/core/worktree").Service | import("./location").LocationMiddleware | import("./middleware/form-location").FormLocationMiddleware | import("./middleware/session-location").SessionLocationMiddleware | import("@opencode/core/pty/ticket").Service | import("@opencode/core/session/transfer").Service | import("effect/unstable/http/HttpRouter").Request<"Requires", import("@opencode/core/database/database").Service> | import("effect/unstable/http/HttpRouter").Request<"Requires", import("@opencode/core/permission/saved").Service> | import("effect/unstable/http/HttpRouter").Request<"Requires", import("@opencode/core/plugin/update").Service> | import("effect/unstable/http/HttpRouter").Request<"Requires", import("./server-info").Service> | import("./pty-environment").Service | import("effect/unstable/http/HttpRouter").Request<"Requires", import("@opencode/core/wellknown").Service> | import("effect/unstable/http/HttpRouter").Request<"Requires", import("@opencode/core/credential").Service> | import("effect/unstable/http/HttpRouter").Request<"Requires", import("@opencode/core/project").Service>>;
|
package/dist/handlers.js
CHANGED
|
@@ -13,7 +13,6 @@ import { RpcHandler } from "./handlers/rpc";
|
|
|
13
13
|
import { EventHandler } from "./handlers/event";
|
|
14
14
|
import { AgentHandler } from "./handlers/agent";
|
|
15
15
|
import { PluginHandler } from "./handlers/plugin";
|
|
16
|
-
import { HealthHandler } from "./handlers/health";
|
|
17
16
|
import { ServerHandler } from "./handlers/server";
|
|
18
17
|
import { DebugHandler } from "./handlers/debug";
|
|
19
18
|
import { PtyHandler } from "./handlers/pty";
|
|
@@ -31,5 +30,4 @@ import { VcsHandler } from "./handlers/vcs";
|
|
|
31
30
|
import { EventFeed } from "./event-feed";
|
|
32
31
|
import { MigrationHandler } from "./handlers/migration";
|
|
33
32
|
import { ConfigHandler } from "./handlers/config";
|
|
34
|
-
|
|
35
|
-
export const handlers = Layer.mergeAll(HealthHandler, ServerHandler, DebugHandler, MigrationHandler, LocationHandler, AgentHandler, PluginHandler, SessionHandler, MessageHandler, ModelHandler, GenerateHandler, ProviderHandler, IntegrationHandler, WebSearchHandler, McpHandler, CredentialHandler, ProjectHandler, FormHandler, PermissionHandler, FileSystemHandler, CommandHandler, SkillHandler, RpcHandler, EventHandler.pipe(Layer.provide(EventFeed.layer)), PtyHandler, PersistentPtyHandler, ShellHandler, ReferenceHandler, WorktreeHandler, WorkspaceHandler, VcsHandler, ConfigHandler);
|
|
33
|
+
export const handlers = Layer.mergeAll(ServerHandler, DebugHandler, MigrationHandler, LocationHandler, AgentHandler, PluginHandler, SessionHandler, MessageHandler, ModelHandler, GenerateHandler, ProviderHandler, IntegrationHandler, WebSearchHandler, McpHandler, CredentialHandler, ProjectHandler, FormHandler, PermissionHandler, FileSystemHandler, CommandHandler, SkillHandler, RpcHandler, EventHandler.pipe(Layer.provide(EventFeed.layer)), PtyHandler, PersistentPtyHandler, ShellHandler, ReferenceHandler, WorktreeHandler, VcsHandler, ConfigHandler);
|
package/dist/location.js
CHANGED
|
@@ -2,7 +2,6 @@ import { Location } from "@opencode/core/location";
|
|
|
2
2
|
import { LocationServiceMap } from "@opencode/core/location-services";
|
|
3
3
|
import { AbsolutePath } from "@opencode/core/schema";
|
|
4
4
|
import { Session } from "@opencode/core/session";
|
|
5
|
-
import { Workspace } from "@opencode/core/workspace";
|
|
6
5
|
import { InvalidRequestError } from "@opencode/protocol/errors";
|
|
7
6
|
import { Effect, Layer, Schema } from "effect";
|
|
8
7
|
import { HttpServerRequest } from "effect/unstable/http";
|
|
@@ -17,7 +16,6 @@ export function response(data) {
|
|
|
17
16
|
return {
|
|
18
17
|
location: new Location.Info({
|
|
19
18
|
directory: location.directory,
|
|
20
|
-
workspaceID: location.workspaceID,
|
|
21
19
|
project: location.project
|
|
22
20
|
}),
|
|
23
21
|
data: yield* data
|
|
@@ -30,10 +28,9 @@ export const sessionInfo = Effect.fnUntraced(function* (sessions, sessionID) {
|
|
|
30
28
|
return yield* sessions.get(id).pipe(Effect.catchTag("Session.NotFoundError", missingSession));
|
|
31
29
|
});
|
|
32
30
|
export function requestRef(request) {
|
|
33
|
-
const
|
|
31
|
+
const directory = new URL(request.url, "http://localhost").searchParams.get("location[directory]") || (request.headers["x-opencode-directory"] ? decode(request.headers["x-opencode-directory"]) : process.cwd());
|
|
34
32
|
return Location.Ref.make({
|
|
35
|
-
directory: AbsolutePath.make(directory)
|
|
36
|
-
workspaceID: workspaceID ? Workspace.ID.make(workspaceID) : void 0
|
|
33
|
+
directory: AbsolutePath.make(directory)
|
|
37
34
|
});
|
|
38
35
|
}
|
|
39
36
|
function decode(input) {
|
package/dist/process.js
CHANGED
|
@@ -27,8 +27,14 @@ export const start = Effect.fn("ServerProcess.start")(function* (options, lifecy
|
|
|
27
27
|
const password = options.password;
|
|
28
28
|
if (!password)
|
|
29
29
|
return yield* Effect.fail(Error("Missing server password"));
|
|
30
|
-
const hostname = options.hostname ?? "127.0.0.1", port = Option.fromNullishOr(options.port), shutdown = yield* Latch.make(), status = yield* Status.make(), bound = yield* listen({ hostname, port }),
|
|
31
|
-
|
|
30
|
+
const hostname = options.hostname ?? "127.0.0.1", port = Option.fromNullishOr(options.port), shutdown = yield* Latch.make(), status = yield* Status.make(), bound = yield* listen({ hostname, port }), urls = () => {
|
|
31
|
+
const address = bound.server.address();
|
|
32
|
+
if (address === null || typeof address === "string")
|
|
33
|
+
return [];
|
|
34
|
+
const host = address.family === "IPv6" ? `[${address.address}]` : address.address;
|
|
35
|
+
return ServerInfo.connectionURLs(`http://${host}:${address.port}`, hostname);
|
|
36
|
+
}, application = yield* Ref.make(Option.none());
|
|
37
|
+
yield* bound.http.serve(dispatch(password, status, application, options.app?.version ?? "unknown", urls).pipe(HttpMiddleware.cors({ allowedOrigins: (origin) => isAllowedCorsOrigin(origin, options), maxAge: 86400 })), errorResponseLogger).pipe(withoutParentSpan);
|
|
32
38
|
if (lifecycle)
|
|
33
39
|
yield* lifecycle.onListen(bound.http.address, shutdown.open.pipe(Effect.asVoid)).pipe(Effect.flatMap((cleanup) => Effect.addFinalizer(() => Scope.close(bound.scope, Exit.void).pipe(Effect.andThen(cleanup)))), Effect.uninterruptible);
|
|
34
40
|
const parentScope = yield* Scope.Scope, applicationScope = yield* Scope.fork(parentScope);
|
|
@@ -37,13 +43,7 @@ export const start = Effect.fn("ServerProcess.start")(function* (options, lifecy
|
|
|
37
43
|
const context = yield* Layer.buildWithScope(createRoutes({
|
|
38
44
|
...options,
|
|
39
45
|
password
|
|
40
|
-
}, ()
|
|
41
|
-
const address = bound.server.address();
|
|
42
|
-
if (address === null || typeof address === "string")
|
|
43
|
-
return [];
|
|
44
|
-
const host = address.family === "IPv6" ? `[${address.address}]` : address.address;
|
|
45
|
-
return ServerInfo.connectionURLs(`http://${host}:${address.port}`, hostname);
|
|
46
|
-
}).pipe(Layer.provideMerge(NodeHttpServer.layerHttpServices)), applicationScope);
|
|
46
|
+
}, urls).pipe(Layer.provideMerge(NodeHttpServer.layerHttpServices)), applicationScope);
|
|
47
47
|
if (lifecycle)
|
|
48
48
|
yield* installRestartContinuity(Context.get(context, SessionRestart.Service)).pipe(Effect.provideService(Scope.Scope, applicationScope));
|
|
49
49
|
const app = Context.get(context, HttpRouter.HttpRouter).asHttpEffect().pipe(HttpMiddleware.compression(), Effect.provideService(HttpPlatform.HttpPlatform, Context.get(context, HttpPlatform.HttpPlatform)));
|
|
@@ -87,14 +87,14 @@ function addressInUse(error) {
|
|
|
87
87
|
const cause = error.cause;
|
|
88
88
|
return typeof cause === "object" && cause !== null && "code" in cause && cause.code === "EADDRINUSE";
|
|
89
89
|
}
|
|
90
|
-
function dispatch(password, status, application, version) {
|
|
90
|
+
function dispatch(password, status, application, version, urls) {
|
|
91
91
|
const auth = ServerAuth.Config.of({ password: Option.some(password), username: "opencode" });
|
|
92
92
|
return Effect.gen(function* () {
|
|
93
93
|
const request = yield* HttpServerRequest.HttpServerRequest, url = new URL(request.url, "http://localhost");
|
|
94
|
-
if (request.method === "GET" && url.pathname === "/api/
|
|
94
|
+
if (request.method === "GET" && url.pathname === "/api/status") {
|
|
95
95
|
if (!(yield* authorizedRequest(request, auth)))
|
|
96
96
|
return unauthorized();
|
|
97
|
-
return yield*
|
|
97
|
+
return yield* statusResponse(status, version, urls);
|
|
98
98
|
}
|
|
99
99
|
const state = yield* status.current, app = yield* Ref.get(application), ready = state.type === "ready" && Option.isSome(app);
|
|
100
100
|
if ((!ready || !hasPtyConnectTicketURL(url) && !hasPersistentPtyConnectTicketURL(url)) && !(yield* authorizedRequest(request, auth)))
|
|
@@ -110,9 +110,9 @@ function unauthorized() {
|
|
|
110
110
|
headers: { "www-authenticate": 'Basic realm="Secure Area"' }
|
|
111
111
|
});
|
|
112
112
|
}
|
|
113
|
-
const
|
|
113
|
+
const statusResponse = Effect.fnUntraced(function* (status, version, urls) {
|
|
114
114
|
const state = yield* status.current;
|
|
115
|
-
return HttpServerResponse.jsonUnsafe({
|
|
115
|
+
return HttpServerResponse.jsonUnsafe({ version, pid: process.pid, urls: urls() }, {
|
|
116
116
|
status: state.type === "ready" ? 200 : state.type === "failed" ? 500 : 503,
|
|
117
117
|
headers: state.type === "starting" || state.type === "stopping" ? { "retry-after": "1" } : void 0
|
|
118
118
|
});
|
package/dist/routes.d.ts
CHANGED
|
@@ -7,6 +7,7 @@ import { PermissionSaved } from "@opencode/core/permission/saved";
|
|
|
7
7
|
import { PtyTicket } from "@opencode/core/pty/ticket";
|
|
8
8
|
import { PersistentPty } from "@opencode/core/persistent-pty";
|
|
9
9
|
import { Project } from "@opencode/core/project";
|
|
10
|
+
import { Worktree } from "@opencode/core/worktree";
|
|
10
11
|
import { Session } from "@opencode/core/session";
|
|
11
12
|
import { Instance } from "@opencode/core/instance/service";
|
|
12
13
|
import { SessionTransfer } from "@opencode/core/session/transfer";
|
|
@@ -23,7 +24,7 @@ import { HttpRouter } from "effect/unstable/http";
|
|
|
23
24
|
import { Layer } from "effect";
|
|
24
25
|
import { PtyEnvironment } from "./pty-environment";
|
|
25
26
|
import type { ServerOptions } from "./options";
|
|
26
|
-
export declare function createRoutes(options?: ServerOptions, serviceURLs?: () => ReadonlyArray<string>, overrides?: LayerNode.Replacements): Layer.Layer<Global.Service | Database.Service | Bus.Service | import("effect/unstable/http/HttpClient").HttpClient | Project.Service | Credential.Service | WellKnown.Service | Workspace.Service | PermissionSaved.Service | PersistentPty.Service | LocationServiceMap.Service | SdkPlugins.Service | PluginUpdate.Service | Session.Service | Job.Service | Instance.Service | SessionRestart.Service | PtyTicket.Service | SessionTransfer.Service | LocationActivity.Service | PtyEnvironment.Service | HttpRouter.HttpRouter, Error | PersistentPty.UnavailableError, import("effect/FileSystem").FileSystem | import("effect/Path").Path | import("effect/unstable/http/Etag").Generator | import("effect/unstable/http/HttpPlatform").HttpPlatform>;
|
|
27
|
+
export declare function createRoutes(options?: ServerOptions, serviceURLs?: () => ReadonlyArray<string>, overrides?: LayerNode.Replacements): Layer.Layer<Global.Service | Database.Service | Bus.Service | import("effect/unstable/http/HttpClient").HttpClient | Project.Service | Credential.Service | WellKnown.Service | Workspace.Service | PermissionSaved.Service | PersistentPty.Service | LocationServiceMap.Service | SdkPlugins.Service | PluginUpdate.Service | Session.Service | Job.Service | Instance.Service | Worktree.Service | SessionRestart.Service | PtyTicket.Service | SessionTransfer.Service | LocationActivity.Service | PtyEnvironment.Service | HttpRouter.HttpRouter, Error | PersistentPty.UnavailableError, import("effect/FileSystem").FileSystem | import("effect/Path").Path | import("effect/unstable/http/Etag").Generator | import("effect/unstable/http/HttpPlatform").HttpPlatform>;
|
|
27
28
|
type InstanceNode = (replacements: () => LayerNode.Replacements) => LayerNode.Provider<Instance.Service, never, typeof Node.tags.values.global>;
|
|
28
|
-
export declare function createEmbeddedRoutes(options?: ServerOptions, overrides?: LayerNode.Replacements, instances?: InstanceNode): Layer.Layer<Global.Service | Database.Service | Bus.Service | import("effect/unstable/http/HttpClient").HttpClient | Project.Service | Credential.Service | WellKnown.Service | Workspace.Service | PermissionSaved.Service | PersistentPty.Service | LocationServiceMap.Service | SdkPlugins.Service | PluginUpdate.Service | Session.Service | Job.Service | Instance.Service | SessionRestart.Service | PtyTicket.Service | SessionTransfer.Service | LocationActivity.Service | PtyEnvironment.Service | HttpRouter.HttpRouter, Error | PersistentPty.UnavailableError, import("effect/FileSystem").FileSystem | import("effect/Path").Path | import("effect/unstable/http/Etag").Generator | import("effect/unstable/http/HttpPlatform").HttpPlatform>;
|
|
29
|
+
export declare function createEmbeddedRoutes(options?: ServerOptions, overrides?: LayerNode.Replacements, instances?: InstanceNode): Layer.Layer<Global.Service | Database.Service | Bus.Service | import("effect/unstable/http/HttpClient").HttpClient | Project.Service | Credential.Service | WellKnown.Service | Workspace.Service | PermissionSaved.Service | PersistentPty.Service | LocationServiceMap.Service | SdkPlugins.Service | PluginUpdate.Service | Session.Service | Job.Service | Instance.Service | Worktree.Service | SessionRestart.Service | PtyTicket.Service | SessionTransfer.Service | LocationActivity.Service | PtyEnvironment.Service | HttpRouter.HttpRouter, Error | PersistentPty.UnavailableError, import("effect/FileSystem").FileSystem | import("effect/Path").Path | import("effect/unstable/http/Etag").Generator | import("effect/unstable/http/HttpPlatform").HttpPlatform>;
|
|
29
30
|
export {};
|
package/dist/routes.js
CHANGED
|
@@ -14,6 +14,7 @@ import { PermissionSaved } from "@opencode/core/permission/saved";
|
|
|
14
14
|
import { PtyTicket } from "@opencode/core/pty/ticket";
|
|
15
15
|
import { PersistentPty } from "@opencode/core/persistent-pty";
|
|
16
16
|
import { Project } from "@opencode/core/project";
|
|
17
|
+
import { Worktree } from "@opencode/core/worktree";
|
|
17
18
|
import { Session } from "@opencode/core/session";
|
|
18
19
|
import { Instance } from "@opencode/core/instance/service";
|
|
19
20
|
import { SessionTransfer } from "@opencode/core/session/transfer";
|
|
@@ -53,6 +54,7 @@ const applicationServiceNodes = [
|
|
|
53
54
|
httpClient,
|
|
54
55
|
Job.node,
|
|
55
56
|
Project.node,
|
|
57
|
+
Worktree.node,
|
|
56
58
|
Session.node,
|
|
57
59
|
Instance.node,
|
|
58
60
|
SessionTransfer.node,
|
|
@@ -110,7 +112,7 @@ function makeRoutes(auth, options, serviceURLs, overrides, instances) {
|
|
|
110
112
|
const { simulationReplacements } = yield* Effect.promise(() => import("@opencode/simulation/backend")), simulation = yield* simulationReplacements({ version: App.make(options.app).version });
|
|
111
113
|
return build([...overrides, ...simulation]);
|
|
112
114
|
})) : build(overrides)).pipe(Layer.flatMap((context) => {
|
|
113
|
-
const services = Layer.succeedContext(context), requestServices = Layer.merge(Layer.succeedContext(Context.pick(Database.Service, PermissionSaved.Service, PluginUpdate.Service, Project.Service, WellKnown.Service)(context)), ServerInfo.layer(serviceURLs, options.app)), api = HttpApiBuilder.layer(Api, { openapiPath: "/openapi.json" }).pipe(Layer.provide(handlers.pipe(Layer.provide(services), Layer.provide(Layer.succeed(CorsConfig, options)))), Layer.provide(formLocationLayer), Layer.provide(sessionLocationLayer), Layer.provide(layer), Layer.provide(authorizationLayer), Layer.provide(schemaErrorLayer), Layer.provide(auth), HttpRouter.provideRequest(requestServices), Layer.provideMerge(services), Layer.provideMerge(HttpRouter.layer));
|
|
115
|
+
const services = Layer.succeedContext(context), requestServices = Layer.merge(Layer.succeedContext(Context.pick(Database.Service, Credential.Service, PermissionSaved.Service, PluginUpdate.Service, Project.Service, WellKnown.Service)(context)), ServerInfo.layer(serviceURLs, options.app)), api = HttpApiBuilder.layer(Api, { openapiPath: "/openapi.json" }).pipe(Layer.provide(handlers.pipe(Layer.provide(services), Layer.provide(Layer.succeed(CorsConfig, options)))), Layer.provide(formLocationLayer), Layer.provide(sessionLocationLayer), Layer.provide(layer), Layer.provide(authorizationLayer), Layer.provide(schemaErrorLayer), Layer.provide(auth), HttpRouter.provideRequest(requestServices), Layer.provideMerge(services), Layer.provideMerge(HttpRouter.layer));
|
|
114
116
|
return Layer.merge(api, V1Migration.layer.pipe(Layer.provide(services)));
|
|
115
117
|
}));
|
|
116
118
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://json.schemastore.org/package.json",
|
|
3
3
|
"name": "@opencode/server",
|
|
4
|
-
"version": "2.0.
|
|
4
|
+
"version": "2.0.5",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"repository": {
|
|
@@ -30,17 +30,17 @@
|
|
|
30
30
|
"dependencies": {
|
|
31
31
|
"@effect/platform-node": "4.0.0-rc.112",
|
|
32
32
|
"@effect/platform-node-shared": "4.0.0-rc.112",
|
|
33
|
-
"@opencode/core": "2.0.
|
|
34
|
-
"@opencode/protocol": "2.0.
|
|
35
|
-
"@opencode/schema": "2.0.
|
|
36
|
-
"@opencode/simulation": "2.0.
|
|
37
|
-
"@opencode/util": "2.0.
|
|
33
|
+
"@opencode/core": "2.0.5",
|
|
34
|
+
"@opencode/protocol": "2.0.5",
|
|
35
|
+
"@opencode/schema": "2.0.5",
|
|
36
|
+
"@opencode/simulation": "2.0.5",
|
|
37
|
+
"@opencode/util": "2.0.5",
|
|
38
38
|
"drizzle-orm": "1.0.0-rc.5-169397b",
|
|
39
39
|
"effect": "4.0.0-rc.112"
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
42
|
-
"@opencode/client": "2.0.
|
|
43
|
-
"@opencode/plugin": "2.0.
|
|
42
|
+
"@opencode/client": "2.0.5",
|
|
43
|
+
"@opencode/plugin": "2.0.5",
|
|
44
44
|
"@tsconfig/bun": "1.0.9",
|
|
45
45
|
"@types/bun": "1.4.0",
|
|
46
46
|
"@typescript/native-preview": "7.0.0-dev.20251207.1"
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import { ServerInfo } from "../server-info";
|
|
2
|
-
export declare const HealthHandler: import("effect/Layer").Layer<import("effect/unstable/httpapi/HttpApiGroup").Service<"server", "server.health">, never, import("@opencode/protocol/middleware/schema-error").SchemaErrorMiddleware | import("@opencode/protocol/middleware/authorization").Authorization | import("effect/unstable/http/HttpRouter").Request<"Requires", ServerInfo.Service>>;
|
package/dist/handlers/health.js
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { Effect } from "effect";
|
|
2
|
-
import { HttpApiBuilder } from "effect/unstable/httpapi";
|
|
3
|
-
import { Api } from "../api";
|
|
4
|
-
import { ServerInfo } from "../server-info";
|
|
5
|
-
export const HealthHandler = HttpApiBuilder.group(Api, "server.health", (handlers) => handlers.handle("health.get", () => Effect.gen(function* () {
|
|
6
|
-
return {
|
|
7
|
-
healthy: !0,
|
|
8
|
-
version: (yield* ServerInfo.Service).app.version ?? "unknown",
|
|
9
|
-
pid: process.pid ?? 0
|
|
10
|
-
};
|
|
11
|
-
})));
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import { Workspace } from "@opencode/core/workspace";
|
|
2
|
-
export declare const WorkspaceHandler: import("effect/Layer").Layer<import("effect/unstable/httpapi/HttpApiGroup").Service<"server", "server.workspace">, never, import("@opencode/protocol/middleware/schema-error").SchemaErrorMiddleware | import("@opencode/protocol/middleware/authorization").Authorization | Workspace.Service>;
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import { Workspace } from "@opencode/core/workspace";
|
|
2
|
-
import { ConflictError, ProviderNotFoundError, UnknownError } from "@opencode/protocol/errors";
|
|
3
|
-
import { Effect } from "effect";
|
|
4
|
-
import { HttpApiBuilder } from "effect/unstable/httpapi";
|
|
5
|
-
import { Api } from "../api";
|
|
6
|
-
export const WorkspaceHandler = HttpApiBuilder.group(Api, "server.workspace", (handlers) => Effect.gen(function* () {
|
|
7
|
-
const workspace = yield* Workspace.Service;
|
|
8
|
-
return handlers.handle("workspace.create", (ctx) => workspace.create(ctx.payload).pipe(Effect.map((workspaceID) => ({ data: workspaceID })), Effect.catchTags({
|
|
9
|
-
"Workspace.CreateConflict": (error) => new ConflictError({
|
|
10
|
-
resource: error.workspaceID,
|
|
11
|
-
message: `Workspace ${error.workspaceID} already uses provider ${error.existingProvider}, not ${error.provider}`
|
|
12
|
-
}),
|
|
13
|
-
"WorkspaceDriver.ProviderNotFound": (error) => new ProviderNotFoundError({
|
|
14
|
-
providerID: error.provider,
|
|
15
|
-
message: `Workspace provider not found: ${error.provider}`
|
|
16
|
-
})
|
|
17
|
-
}))).handle("workspace.destroy", (ctx) => workspace.destroy(ctx.params.workspaceID).pipe(Effect.mapError((error) => new UnknownError({
|
|
18
|
-
message: error._tag === "WorkspaceDriver.ProviderNotFound" ? `Workspace provider not found: ${error.provider}` : error.message ?? "Workspace provider failed to destroy the workspace"
|
|
19
|
-
}))));
|
|
20
|
-
}));
|