@opencode/server 2.0.4 → 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 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: {
@@ -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
- 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 | import("../location").LocationMiddleware>;
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 { Effect } from "effect";
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) => handlers.handle("location.get", Effect.fn(function* () {
6
- const location = yield* Location.Service;
7
- return new Location.Info({
8
- directory: location.directory,
9
- project: location.project
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
+ }));
@@ -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.status", () => Effect.gen(function* () {
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/status") {
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* statusResponse(status, version, urls);
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 statusResponse = Effect.fnUntraced(function* (status, version, urls) {
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
  }
@@ -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";
@@ -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",
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.4",
34
- "@opencode/protocol": "2.0.4",
35
- "@opencode/schema": "2.0.4",
36
- "@opencode/simulation": "2.0.4",
37
- "@opencode/util": "2.0.4",
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.4",
43
- "@opencode/plugin": "2.0.4",
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"