@opencode/server 2.0.5 → 2.0.6
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 +44 -0
- package/dist/handlers/fs.js +2 -0
- package/dist/handlers/location.d.ts +2 -1
- package/dist/handlers/location.js +13 -8
- package/dist/handlers/server.js +3 -2
- package/dist/process.js +8 -8
- package/dist/routes.js +1 -1
- package/dist/server-info.d.ts +4 -1
- package/dist/server-info.js +2 -2
- package/dist/workerd.js +2 -1
- package/package.json +8 -8
package/dist/api.d.ts
CHANGED
|
@@ -2,6 +2,38 @@ import { LocationMiddleware } from "./location";
|
|
|
2
2
|
import { FormLocationMiddleware } from "./middleware/form-location";
|
|
3
3
|
import { SessionLocationMiddleware } from "./middleware/session-location";
|
|
4
4
|
export declare const Api: import("@opencode/protocol/api").Api<LocationMiddleware, import("effect/unstable/httpapi/HttpApiMiddleware").HttpApiMiddleware<import("@opencode/core/instance").Services, never, never>, FormLocationMiddleware, import("effect/unstable/httpapi/HttpApiMiddleware").HttpApiMiddleware<import("@opencode/core/instance").Services, readonly [typeof import("@opencode/protocol/errors").InvalidRequestError, typeof import("@opencode/protocol/errors").SessionNotFoundError], never>, SessionLocationMiddleware, import("effect/unstable/httpapi/HttpApiMiddleware").HttpApiMiddleware<import("@opencode/core/instance").Services, readonly [typeof import("@opencode/protocol/errors").InvalidRequestError, typeof import("@opencode/protocol/errors").SessionNotFoundError], never>, import("effect/unstable/httpapi/HttpApiGroup").HttpApiGroup<"server.event", import("effect/unstable/httpapi/HttpApiEndpoint").HttpApiEndpoint<"event.subscribe", "GET", "/api/event", never, never, never, never, import("effect/unstable/httpapi/HttpApiSchema").StreamSse<import("effect/unstable/httpapi/HttpApiSchema").SseEventFromData<import("effect/Schema").Union<readonly [import("effect/Schema").Struct<{
|
|
5
|
+
readonly id: import("effect/Schema").brand<import("effect/Schema").String, "Event.ID"> & {
|
|
6
|
+
create: () => string & import("effect/Brand").Brand<"Event.ID">;
|
|
7
|
+
};
|
|
8
|
+
readonly created: import("effect/Schema").Finite;
|
|
9
|
+
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>;
|
|
10
|
+
readonly type: import("effect/Schema").Literal<"location.shutdown">;
|
|
11
|
+
readonly location: import("effect/Schema").decodeTo<import("effect/Schema").optional<import("effect/Schema").toType<import("effect/Schema").Struct<{
|
|
12
|
+
readonly directory: import("effect/Schema").brand<import("effect/Schema").String, "AbsolutePath">;
|
|
13
|
+
readonly workspaceID: import("effect/Schema").decodeTo<import("effect/Schema").optional<import("effect/Schema").toType<import("effect/Schema").brand<import("effect/Schema").String, "Workspace.ID"> & {
|
|
14
|
+
ascending: (id?: string) => string & import("effect/Brand").Brand<"Workspace.ID">;
|
|
15
|
+
create: () => string & import("effect/Brand").Brand<"Workspace.ID">;
|
|
16
|
+
}>>, import("effect/Schema").optionalKey<import("effect/Schema").brand<import("effect/Schema").String, "Workspace.ID"> & {
|
|
17
|
+
ascending: (id?: string) => string & import("effect/Brand").Brand<"Workspace.ID">;
|
|
18
|
+
create: () => string & import("effect/Brand").Brand<"Workspace.ID">;
|
|
19
|
+
}>, never, never>;
|
|
20
|
+
}>>>, import("effect/Schema").optionalKey<import("effect/Schema").Struct<{
|
|
21
|
+
readonly directory: import("effect/Schema").brand<import("effect/Schema").String, "AbsolutePath">;
|
|
22
|
+
readonly workspaceID: import("effect/Schema").decodeTo<import("effect/Schema").optional<import("effect/Schema").toType<import("effect/Schema").brand<import("effect/Schema").String, "Workspace.ID"> & {
|
|
23
|
+
ascending: (id?: string) => string & import("effect/Brand").Brand<"Workspace.ID">;
|
|
24
|
+
create: () => string & import("effect/Brand").Brand<"Workspace.ID">;
|
|
25
|
+
}>>, import("effect/Schema").optionalKey<import("effect/Schema").brand<import("effect/Schema").String, "Workspace.ID"> & {
|
|
26
|
+
ascending: (id?: string) => string & import("effect/Brand").Brand<"Workspace.ID">;
|
|
27
|
+
create: () => string & import("effect/Brand").Brand<"Workspace.ID">;
|
|
28
|
+
}>, never, never>;
|
|
29
|
+
}>>, never, never>;
|
|
30
|
+
readonly data: import("effect/Schema").Struct<{}>;
|
|
31
|
+
}> & {
|
|
32
|
+
type: "location.shutdown";
|
|
33
|
+
durability: "ephemeral";
|
|
34
|
+
durable: undefined;
|
|
35
|
+
data: import("effect/Schema").Struct<{}>;
|
|
36
|
+
}, import("effect/Schema").Struct<{
|
|
5
37
|
readonly id: import("effect/Schema").brand<import("effect/Schema").String, "Event.ID"> & {
|
|
6
38
|
create: () => string & import("effect/Brand").Brand<"Event.ID">;
|
|
7
39
|
};
|
|
@@ -8086,6 +8118,18 @@ export declare const Api: import("@opencode/protocol/api").Api<LocationMiddlewar
|
|
|
8086
8118
|
readonly metadata?: {
|
|
8087
8119
|
readonly [x: string]: unknown;
|
|
8088
8120
|
} | undefined;
|
|
8121
|
+
} | {
|
|
8122
|
+
readonly id: string & import("effect/Brand").Brand<"Event.ID">;
|
|
8123
|
+
readonly data: {};
|
|
8124
|
+
readonly type: "location.shutdown";
|
|
8125
|
+
readonly created: number;
|
|
8126
|
+
readonly location?: {
|
|
8127
|
+
readonly directory: string & import("effect/Brand").Brand<"AbsolutePath">;
|
|
8128
|
+
readonly workspaceID?: (string & import("effect/Brand").Brand<"Workspace.ID">) | undefined;
|
|
8129
|
+
} | undefined;
|
|
8130
|
+
readonly metadata?: {
|
|
8131
|
+
readonly [x: string]: unknown;
|
|
8132
|
+
} | undefined;
|
|
8089
8133
|
} | {
|
|
8090
8134
|
readonly id: string & import("effect/Brand").Brand<"Event.ID">;
|
|
8091
8135
|
readonly data: {
|
package/dist/handlers/fs.js
CHANGED
|
@@ -16,5 +16,7 @@ export const FileSystemHandler = HttpApiBuilder.group(Api, "server.fs", (handler
|
|
|
16
16
|
return yield* (yield* FileSystem.Service).list(ctx.query);
|
|
17
17
|
}))).handle("fs.find", (ctx) => response(Effect.gen(function* () {
|
|
18
18
|
return yield* (yield* FileSystem.Service).find(ctx.query);
|
|
19
|
+
}))).handle("fs.write", (ctx) => response(Effect.gen(function* () {
|
|
20
|
+
return yield* (yield* FileSystem.Service).write({ path: ctx.query.path, data: ctx.payload });
|
|
19
21
|
})));
|
|
20
22
|
}));
|
|
@@ -1 +1,2 @@
|
|
|
1
|
-
|
|
1
|
+
import { LocationServiceMap } from "@opencode/core/location-service-map";
|
|
2
|
+
export declare const LocationHandler: import("effect/Layer").Layer<import("effect/unstable/httpapi/HttpApiGroup").Service<"server", "server.location">, never, import("@opencode/protocol/middleware/schema-error").SchemaErrorMiddleware | import("@opencode/protocol/middleware/authorization").Authorization | LocationServiceMap.Service | import("../location").LocationMiddleware>;
|
|
@@ -1,11 +1,16 @@
|
|
|
1
1
|
import { Location } from "@opencode/core/location";
|
|
2
|
-
import {
|
|
2
|
+
import { LocationServiceMap } from "@opencode/core/location-service-map";
|
|
3
|
+
import { ServiceUnavailableError } from "@opencode/protocol/errors";
|
|
4
|
+
import { Cause, Effect } from "effect";
|
|
3
5
|
import { HttpApiBuilder } from "effect/unstable/httpapi";
|
|
4
6
|
import { Api } from "../api";
|
|
5
|
-
export const LocationHandler = HttpApiBuilder.group(Api, "server.location", (handlers) =>
|
|
6
|
-
const
|
|
7
|
-
return
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
7
|
+
export const LocationHandler = HttpApiBuilder.group(Api, "server.location", (handlers) => Effect.gen(function* () {
|
|
8
|
+
const locations = yield* LocationServiceMap.Service;
|
|
9
|
+
return handlers.handle("location.get", Effect.fn(function* () {
|
|
10
|
+
const location = yield* Location.Service;
|
|
11
|
+
return new Location.Info({
|
|
12
|
+
directory: location.directory,
|
|
13
|
+
project: location.project
|
|
14
|
+
});
|
|
15
|
+
})).handle("location.reload", () => LocationServiceMap.reload().pipe(Effect.provideService(LocationServiceMap.Service, locations), Effect.catchCause((cause) => Cause.hasInterruptsOnly(cause) ? Effect.failCause(cause) : Effect.fail(new ServiceUnavailableError({ message: Cause.pretty(cause), service: "location" })))));
|
|
16
|
+
}));
|
package/dist/handlers/server.js
CHANGED
|
@@ -2,11 +2,12 @@ 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.
|
|
5
|
+
export const ServerHandler = HttpApiBuilder.group(Api, "server.server", (handlers) => handlers.handle("server.info", () => Effect.gen(function* () {
|
|
6
6
|
const info = yield* ServerInfo.Service;
|
|
7
7
|
return {
|
|
8
8
|
version: info.app.version ?? "unknown",
|
|
9
9
|
pid: process.pid ?? 0,
|
|
10
|
-
urls: info.urls()
|
|
10
|
+
urls: info.urls(),
|
|
11
|
+
paths: info.paths
|
|
11
12
|
};
|
|
12
13
|
})));
|
package/dist/process.js
CHANGED
|
@@ -5,6 +5,7 @@ import { SessionRestart } from "@opencode/core/session/execution/restart";
|
|
|
5
5
|
import { InstallationEvent } from "@opencode/schema/installation-event";
|
|
6
6
|
import { hasPtyConnectTicketURL } from "@opencode/protocol/groups/pty";
|
|
7
7
|
import { hasPersistentPtyConnectTicketURL } from "@opencode/protocol/groups/persistent-pty";
|
|
8
|
+
import { Global } from "@opencode/util/global";
|
|
8
9
|
import { Cause, Context, Effect, Exit, Latch, Layer, Option, Ref, Scope } from "effect";
|
|
9
10
|
import {
|
|
10
11
|
HttpMiddleware,
|
|
@@ -34,7 +35,7 @@ export const start = Effect.fn("ServerProcess.start")(function* (options, lifecy
|
|
|
34
35
|
const host = address.family === "IPv6" ? `[${address.address}]` : address.address;
|
|
35
36
|
return ServerInfo.connectionURLs(`http://${host}:${address.port}`, hostname);
|
|
36
37
|
}, 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);
|
|
38
|
+
yield* bound.http.serve(dispatch(password, status, application, options.app?.version ?? "unknown", urls, Global.Path.tmp).pipe(HttpMiddleware.cors({ allowedOrigins: (origin) => isAllowedCorsOrigin(origin, options), maxAge: 86400 })), errorResponseLogger).pipe(withoutParentSpan);
|
|
38
39
|
if (lifecycle)
|
|
39
40
|
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);
|
|
40
41
|
const parentScope = yield* Scope.Scope, applicationScope = yield* Scope.fork(parentScope);
|
|
@@ -87,16 +88,15 @@ function addressInUse(error) {
|
|
|
87
88
|
const cause = error.cause;
|
|
88
89
|
return typeof cause === "object" && cause !== null && "code" in cause && cause.code === "EADDRINUSE";
|
|
89
90
|
}
|
|
90
|
-
function dispatch(password, status, application, version, urls) {
|
|
91
|
+
function dispatch(password, status, application, version, urls, tmp) {
|
|
91
92
|
const auth = ServerAuth.Config.of({ password: Option.some(password), username: "opencode" });
|
|
92
93
|
return Effect.gen(function* () {
|
|
93
|
-
const request = yield* HttpServerRequest.HttpServerRequest, url = new URL(request.url, "http://localhost");
|
|
94
|
-
if (request.method === "GET" && url.pathname === "/api/
|
|
94
|
+
const request = yield* HttpServerRequest.HttpServerRequest, url = new URL(request.url, "http://localhost"), state = yield* status.current, app = yield* Ref.get(application), ready = state.type === "ready" && Option.isSome(app);
|
|
95
|
+
if (request.method === "GET" && url.pathname === "/api/info" && !ready) {
|
|
95
96
|
if (!(yield* authorizedRequest(request, auth)))
|
|
96
97
|
return unauthorized();
|
|
97
|
-
return yield*
|
|
98
|
+
return yield* infoResponse(status, version, urls, tmp);
|
|
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)))
|
|
101
101
|
return unauthorized();
|
|
102
102
|
if (ready)
|
|
@@ -110,9 +110,9 @@ function unauthorized() {
|
|
|
110
110
|
headers: { "www-authenticate": 'Basic realm="Secure Area"' }
|
|
111
111
|
});
|
|
112
112
|
}
|
|
113
|
-
const
|
|
113
|
+
const infoResponse = Effect.fnUntraced(function* (status, version, urls, tmp) {
|
|
114
114
|
const state = yield* status.current;
|
|
115
|
-
return HttpServerResponse.jsonUnsafe({ version, pid: process.pid, urls: urls() }, {
|
|
115
|
+
return HttpServerResponse.jsonUnsafe({ version, pid: process.pid, urls: urls(), paths: { tmp } }, {
|
|
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.js
CHANGED
|
@@ -112,7 +112,7 @@ function makeRoutes(auth, options, serviceURLs, overrides, instances) {
|
|
|
112
112
|
const { simulationReplacements } = yield* Effect.promise(() => import("@opencode/simulation/backend")), simulation = yield* simulationReplacements({ version: App.make(options.app).version });
|
|
113
113
|
return build([...overrides, ...simulation]);
|
|
114
114
|
})) : build(overrides)).pipe(Layer.flatMap((context) => {
|
|
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));
|
|
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, Context.get(context, Global.Service).tmp, 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));
|
|
116
116
|
return Layer.merge(api, V1Migration.layer.pipe(Layer.provide(services)));
|
|
117
117
|
}));
|
|
118
118
|
}
|
package/dist/server-info.d.ts
CHANGED
|
@@ -3,9 +3,12 @@ import type { ServerOptions } from "./options";
|
|
|
3
3
|
declare const Service_base: Context.ServiceClass<Service, "@opencode/server/ServerInfo", {
|
|
4
4
|
readonly urls: () => ReadonlyArray<string>;
|
|
5
5
|
readonly app: NonNullable<ServerOptions["app"]>;
|
|
6
|
+
readonly paths: {
|
|
7
|
+
readonly tmp: string;
|
|
8
|
+
};
|
|
6
9
|
}>;
|
|
7
10
|
export declare class Service extends Service_base {
|
|
8
11
|
}
|
|
9
|
-
export declare function layer(urls: () => ReadonlyArray<string>, app?: ServerOptions["app"]): Layer.Layer<Service, never, never>;
|
|
12
|
+
export declare function layer(urls: () => ReadonlyArray<string>, tmp: string, app?: ServerOptions["app"]): Layer.Layer<Service, never, never>;
|
|
10
13
|
export declare function connectionURLs(value: string, requestedHostname?: string): string[];
|
|
11
14
|
export * as ServerInfo from "./server-info";
|
package/dist/server-info.js
CHANGED
|
@@ -3,8 +3,8 @@ import { networkInterfaces } from "node:os";
|
|
|
3
3
|
|
|
4
4
|
export class Service extends Context.Service()("@opencode/server/ServerInfo") {
|
|
5
5
|
}
|
|
6
|
-
export function layer(urls, app = {}) {
|
|
7
|
-
return Layer.succeed(Service, Service.of({ urls, app }));
|
|
6
|
+
export function layer(urls, tmp, app = {}) {
|
|
7
|
+
return Layer.succeed(Service, Service.of({ urls, app, paths: { tmp } }));
|
|
8
8
|
}
|
|
9
9
|
export function connectionURLs(value, requestedHostname) {
|
|
10
10
|
const url = new URL(value), hostname = requestedHostname ?? url.hostname, family = hostname === "0.0.0.0" ? "IPv4" : hostname === "::" || hostname === "[::]" ? "IPv6" : void 0;
|
package/dist/workerd.js
CHANGED
|
@@ -47,7 +47,8 @@ const unavailable = (what) => Effect.die(Error(`${what} is unavailable in the wo
|
|
|
47
47
|
})), fileSystemLayer = Layer.succeed(FileSystem.Service, FileSystem.Service.of({
|
|
48
48
|
read: () => unavailable("FileSystem.read"),
|
|
49
49
|
list: () => unavailable("FileSystem.list"),
|
|
50
|
-
find: () => unavailable("FileSystem.find")
|
|
50
|
+
find: () => unavailable("FileSystem.find"),
|
|
51
|
+
write: () => unavailable("FileSystem.write")
|
|
51
52
|
})), fileSystemSearchLayer = Layer.succeed(FileSystemSearch.Service, FileSystemSearch.Service.of({
|
|
52
53
|
find: () => unavailable("FileSystemSearch.find")
|
|
53
54
|
})), ptyLayer = Layer.succeed(Pty.Service, Pty.Service.of({
|
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.6",
|
|
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.6",
|
|
34
|
+
"@opencode/protocol": "2.0.6",
|
|
35
|
+
"@opencode/schema": "2.0.6",
|
|
36
|
+
"@opencode/simulation": "2.0.6",
|
|
37
|
+
"@opencode/util": "2.0.6",
|
|
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.6",
|
|
43
|
+
"@opencode/plugin": "2.0.6",
|
|
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"
|