@opencode-ai/server 0.0.0-beta-18593 → 0.0.0-beta-18684

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
@@ -1,7 +1,7 @@
1
1
  import { LocationMiddleware } from "./location";
2
2
  import { FormLocationMiddleware } from "./middleware/form-location";
3
3
  import { SessionLocationMiddleware } from "./middleware/session-location";
4
- export declare const Api: import("@opencode-ai/protocol/api").Api<LocationMiddleware, import("effect/unstable/httpapi/HttpApiMiddleware").HttpApiMiddleware<import("@opencode-ai/core/location").Service | import("@opencode-ai/core/config").Service | import("@opencode-ai/core/agent").Service | import("@opencode-ai/core/aisdk").Service | import("@opencode-ai/core/form").Service | import("@opencode-ai/core/integration").Service | import("@opencode-ai/core/catalog").Service | import("@opencode-ai/core/command").Service | import("@opencode-ai/core/environment/environment").Service | import("@opencode-ai/core/mcp/index").Service | import("@opencode-ai/core/file-mutation").Service | import("@opencode-ai/core/formatter").Service | import("@opencode-ai/core/filesystem/search").Service | import("@opencode-ai/core/filesystem").Service | import("@opencode-ai/core/model-resolver").Service | import("@opencode-ai/core/generate").Service | import("@opencode-ai/core/image").Service | import("@opencode-ai/core/plugin/supervisor-service").Service | import("@opencode-ai/core/plugin/instance").Service | import("@opencode-ai/core/plugin/hooks").Service | import("@opencode-ai/core/permission").Service | import("@opencode-ai/core/location-mutation").Service | import("@opencode-ai/core/session/instructions").Service | import("@opencode-ai/core/tool/read-filesystem").Service | import("@opencode-ai/core/shell/select").Service | import("@opencode-ai/core/instruction-discovery").Service | import("@opencode-ai/core/instructions/builtins").Service | import("@opencode-ai/core/tool").Service | import("@opencode-ai/core/tool/mcp").Service | import("@opencode-ai/core/reference").Service | import("@opencode-ai/core/reference/instructions").Service | import("@opencode-ai/core/skill").Service | import("@opencode-ai/core/skill/instructions").Service | import("@opencode-ai/core/session/instruction-entry").Service | import("@opencode-ai/core/session/model-transport").Service | import("@opencode-ai/core/session/runner/model").Service | import("@opencode-ai/core/plugin").Service | import("@opencode-ai/core/shell").Service | import("@opencode-ai/core/websearch").Service | import("@opencode-ai/core/session/compaction").Service | import("@opencode-ai/core/snapshot").Service | import("@opencode-ai/core/tool-output").Service | import("@opencode-ai/core/vcs").Service | import("@opencode-ai/core/filesystem/location-watcher").Service | import("@opencode-ai/core/pty").Service | import("@opencode-ai/core/session/title").Service | import("@opencode-ai/core/session/runner/index").Service | import("@opencode-ai/core/session/generate").Service, never, never>, FormLocationMiddleware, import("effect/unstable/httpapi/HttpApiMiddleware").HttpApiMiddleware<import("@opencode-ai/core/location").Service | import("@opencode-ai/core/config").Service | import("@opencode-ai/core/agent").Service | import("@opencode-ai/core/aisdk").Service | import("@opencode-ai/core/form").Service | import("@opencode-ai/core/integration").Service | import("@opencode-ai/core/catalog").Service | import("@opencode-ai/core/command").Service | import("@opencode-ai/core/environment/environment").Service | import("@opencode-ai/core/mcp/index").Service | import("@opencode-ai/core/file-mutation").Service | import("@opencode-ai/core/formatter").Service | import("@opencode-ai/core/filesystem/search").Service | import("@opencode-ai/core/filesystem").Service | import("@opencode-ai/core/model-resolver").Service | import("@opencode-ai/core/generate").Service | import("@opencode-ai/core/image").Service | import("@opencode-ai/core/plugin/supervisor-service").Service | import("@opencode-ai/core/plugin/instance").Service | import("@opencode-ai/core/plugin/hooks").Service | import("@opencode-ai/core/permission").Service | import("@opencode-ai/core/location-mutation").Service | import("@opencode-ai/core/session/instructions").Service | import("@opencode-ai/core/tool/read-filesystem").Service | import("@opencode-ai/core/shell/select").Service | import("@opencode-ai/core/instruction-discovery").Service | import("@opencode-ai/core/instructions/builtins").Service | import("@opencode-ai/core/tool").Service | import("@opencode-ai/core/tool/mcp").Service | import("@opencode-ai/core/reference").Service | import("@opencode-ai/core/reference/instructions").Service | import("@opencode-ai/core/skill").Service | import("@opencode-ai/core/skill/instructions").Service | import("@opencode-ai/core/session/instruction-entry").Service | import("@opencode-ai/core/session/model-transport").Service | import("@opencode-ai/core/session/runner/model").Service | import("@opencode-ai/core/plugin").Service | import("@opencode-ai/core/shell").Service | import("@opencode-ai/core/websearch").Service | import("@opencode-ai/core/session/compaction").Service | import("@opencode-ai/core/snapshot").Service | import("@opencode-ai/core/tool-output").Service | import("@opencode-ai/core/vcs").Service | import("@opencode-ai/core/filesystem/location-watcher").Service | import("@opencode-ai/core/pty").Service | import("@opencode-ai/core/session/title").Service | import("@opencode-ai/core/session/runner/index").Service | import("@opencode-ai/core/session/generate").Service, readonly [typeof import("@opencode-ai/protocol/errors").InvalidRequestError, typeof import("@opencode-ai/protocol/errors").SessionNotFoundError], never>, SessionLocationMiddleware, import("effect/unstable/httpapi/HttpApiMiddleware").HttpApiMiddleware<import("@opencode-ai/core/location").Service | import("@opencode-ai/core/config").Service | import("@opencode-ai/core/agent").Service | import("@opencode-ai/core/aisdk").Service | import("@opencode-ai/core/form").Service | import("@opencode-ai/core/integration").Service | import("@opencode-ai/core/catalog").Service | import("@opencode-ai/core/command").Service | import("@opencode-ai/core/environment/environment").Service | import("@opencode-ai/core/mcp/index").Service | import("@opencode-ai/core/file-mutation").Service | import("@opencode-ai/core/formatter").Service | import("@opencode-ai/core/filesystem/search").Service | import("@opencode-ai/core/filesystem").Service | import("@opencode-ai/core/model-resolver").Service | import("@opencode-ai/core/generate").Service | import("@opencode-ai/core/image").Service | import("@opencode-ai/core/plugin/supervisor-service").Service | import("@opencode-ai/core/plugin/instance").Service | import("@opencode-ai/core/plugin/hooks").Service | import("@opencode-ai/core/permission").Service | import("@opencode-ai/core/location-mutation").Service | import("@opencode-ai/core/session/instructions").Service | import("@opencode-ai/core/tool/read-filesystem").Service | import("@opencode-ai/core/shell/select").Service | import("@opencode-ai/core/instruction-discovery").Service | import("@opencode-ai/core/instructions/builtins").Service | import("@opencode-ai/core/tool").Service | import("@opencode-ai/core/tool/mcp").Service | import("@opencode-ai/core/reference").Service | import("@opencode-ai/core/reference/instructions").Service | import("@opencode-ai/core/skill").Service | import("@opencode-ai/core/skill/instructions").Service | import("@opencode-ai/core/session/instruction-entry").Service | import("@opencode-ai/core/session/model-transport").Service | import("@opencode-ai/core/session/runner/model").Service | import("@opencode-ai/core/plugin").Service | import("@opencode-ai/core/shell").Service | import("@opencode-ai/core/websearch").Service | import("@opencode-ai/core/session/compaction").Service | import("@opencode-ai/core/snapshot").Service | import("@opencode-ai/core/tool-output").Service | import("@opencode-ai/core/vcs").Service | import("@opencode-ai/core/filesystem/location-watcher").Service | import("@opencode-ai/core/pty").Service | import("@opencode-ai/core/session/title").Service | import("@opencode-ai/core/session/runner/index").Service | import("@opencode-ai/core/session/generate").Service, readonly [typeof import("@opencode-ai/protocol/errors").InvalidRequestError, typeof import("@opencode-ai/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<{
4
+ export declare const Api: import("@opencode-ai/protocol/api").Api<LocationMiddleware, import("effect/unstable/httpapi/HttpApiMiddleware").HttpApiMiddleware<import("@opencode-ai/core/location").Service | import("@opencode-ai/core/config").Service | import("@opencode-ai/core/agent").Service | import("@opencode-ai/core/aisdk").Service | import("@opencode-ai/core/form").Service | import("@opencode-ai/core/integration").Service | import("@opencode-ai/core/catalog").Service | import("@opencode-ai/core/command").Service | import("@opencode-ai/core/environment/environment").Service | import("@opencode-ai/core/mcp/index").Service | import("@opencode-ai/core/file-mutation").Service | import("@opencode-ai/core/formatter").Service | import("@opencode-ai/core/filesystem/search").Service | import("@opencode-ai/core/filesystem").Service | import("@opencode-ai/core/model-resolver").Service | import("@opencode-ai/core/generate").Service | import("@opencode-ai/core/image").Service | import("@opencode-ai/core/plugin/supervisor-service").Service | import("@opencode-ai/core/plugin/instance").Service | import("@opencode-ai/core/plugin/hooks").Service | import("@opencode-ai/core/permission").Service | import("@opencode-ai/core/location-mutation").Service | import("@opencode-ai/core/session/instructions").Service | import("@opencode-ai/core/tool/read-filesystem").Service | import("@opencode-ai/core/shell/select").Service | import("@opencode-ai/core/instruction-discovery").Service | import("@opencode-ai/core/instructions/builtins").Service | import("@opencode-ai/core/tool").Service | import("@opencode-ai/core/tool/mcp").Service | import("@opencode-ai/core/reference").Service | import("@opencode-ai/core/reference/instructions").Service | import("@opencode-ai/core/skill").Service | import("@opencode-ai/core/skill/instructions").Service | import("@opencode-ai/core/session/instruction-entry").Service | import("@opencode-ai/core/session/model-transport").Service | import("@opencode-ai/core/session/runner/model").Service | import("@opencode-ai/core/plugin").Service | import("@opencode-ai/core/shell").Service | import("@opencode-ai/core/session/prompt").Service | import("@opencode-ai/core/session/revert").Service | import("@opencode-ai/core/websearch").Service | import("@opencode-ai/core/session/compaction").Service | import("@opencode-ai/core/snapshot").Service | import("@opencode-ai/core/tool-output").Service | import("@opencode-ai/core/vcs").Service | import("@opencode-ai/core/session/runner/index").Service | import("@opencode-ai/core/pty").Service | import("@opencode-ai/core/session/generate").Service | import("@opencode-ai/core/session/title").Service | import("@opencode-ai/core/filesystem/location-watcher").Service, never, never>, FormLocationMiddleware, import("effect/unstable/httpapi/HttpApiMiddleware").HttpApiMiddleware<import("@opencode-ai/core/location").Service | import("@opencode-ai/core/config").Service | import("@opencode-ai/core/agent").Service | import("@opencode-ai/core/aisdk").Service | import("@opencode-ai/core/form").Service | import("@opencode-ai/core/integration").Service | import("@opencode-ai/core/catalog").Service | import("@opencode-ai/core/command").Service | import("@opencode-ai/core/environment/environment").Service | import("@opencode-ai/core/mcp/index").Service | import("@opencode-ai/core/file-mutation").Service | import("@opencode-ai/core/formatter").Service | import("@opencode-ai/core/filesystem/search").Service | import("@opencode-ai/core/filesystem").Service | import("@opencode-ai/core/model-resolver").Service | import("@opencode-ai/core/generate").Service | import("@opencode-ai/core/image").Service | import("@opencode-ai/core/plugin/supervisor-service").Service | import("@opencode-ai/core/plugin/instance").Service | import("@opencode-ai/core/plugin/hooks").Service | import("@opencode-ai/core/permission").Service | import("@opencode-ai/core/location-mutation").Service | import("@opencode-ai/core/session/instructions").Service | import("@opencode-ai/core/tool/read-filesystem").Service | import("@opencode-ai/core/shell/select").Service | import("@opencode-ai/core/instruction-discovery").Service | import("@opencode-ai/core/instructions/builtins").Service | import("@opencode-ai/core/tool").Service | import("@opencode-ai/core/tool/mcp").Service | import("@opencode-ai/core/reference").Service | import("@opencode-ai/core/reference/instructions").Service | import("@opencode-ai/core/skill").Service | import("@opencode-ai/core/skill/instructions").Service | import("@opencode-ai/core/session/instruction-entry").Service | import("@opencode-ai/core/session/model-transport").Service | import("@opencode-ai/core/session/runner/model").Service | import("@opencode-ai/core/plugin").Service | import("@opencode-ai/core/shell").Service | import("@opencode-ai/core/session/prompt").Service | import("@opencode-ai/core/session/revert").Service | import("@opencode-ai/core/websearch").Service | import("@opencode-ai/core/session/compaction").Service | import("@opencode-ai/core/snapshot").Service | import("@opencode-ai/core/tool-output").Service | import("@opencode-ai/core/vcs").Service | import("@opencode-ai/core/session/runner/index").Service | import("@opencode-ai/core/pty").Service | import("@opencode-ai/core/session/generate").Service | import("@opencode-ai/core/session/title").Service | import("@opencode-ai/core/filesystem/location-watcher").Service, readonly [typeof import("@opencode-ai/protocol/errors").InvalidRequestError, typeof import("@opencode-ai/protocol/errors").SessionNotFoundError], never>, SessionLocationMiddleware, import("effect/unstable/httpapi/HttpApiMiddleware").HttpApiMiddleware<import("@opencode-ai/core/location").Service | import("@opencode-ai/core/config").Service | import("@opencode-ai/core/agent").Service | import("@opencode-ai/core/aisdk").Service | import("@opencode-ai/core/form").Service | import("@opencode-ai/core/integration").Service | import("@opencode-ai/core/catalog").Service | import("@opencode-ai/core/command").Service | import("@opencode-ai/core/environment/environment").Service | import("@opencode-ai/core/mcp/index").Service | import("@opencode-ai/core/file-mutation").Service | import("@opencode-ai/core/formatter").Service | import("@opencode-ai/core/filesystem/search").Service | import("@opencode-ai/core/filesystem").Service | import("@opencode-ai/core/model-resolver").Service | import("@opencode-ai/core/generate").Service | import("@opencode-ai/core/image").Service | import("@opencode-ai/core/plugin/supervisor-service").Service | import("@opencode-ai/core/plugin/instance").Service | import("@opencode-ai/core/plugin/hooks").Service | import("@opencode-ai/core/permission").Service | import("@opencode-ai/core/location-mutation").Service | import("@opencode-ai/core/session/instructions").Service | import("@opencode-ai/core/tool/read-filesystem").Service | import("@opencode-ai/core/shell/select").Service | import("@opencode-ai/core/instruction-discovery").Service | import("@opencode-ai/core/instructions/builtins").Service | import("@opencode-ai/core/tool").Service | import("@opencode-ai/core/tool/mcp").Service | import("@opencode-ai/core/reference").Service | import("@opencode-ai/core/reference/instructions").Service | import("@opencode-ai/core/skill").Service | import("@opencode-ai/core/skill/instructions").Service | import("@opencode-ai/core/session/instruction-entry").Service | import("@opencode-ai/core/session/model-transport").Service | import("@opencode-ai/core/session/runner/model").Service | import("@opencode-ai/core/plugin").Service | import("@opencode-ai/core/shell").Service | import("@opencode-ai/core/session/prompt").Service | import("@opencode-ai/core/session/revert").Service | import("@opencode-ai/core/websearch").Service | import("@opencode-ai/core/session/compaction").Service | import("@opencode-ai/core/snapshot").Service | import("@opencode-ai/core/tool-output").Service | import("@opencode-ai/core/vcs").Service | import("@opencode-ai/core/session/runner/index").Service | import("@opencode-ai/core/pty").Service | import("@opencode-ai/core/session/generate").Service | import("@opencode-ai/core/session/title").Service | import("@opencode-ai/core/filesystem/location-watcher").Service, readonly [typeof import("@opencode-ai/protocol/errors").InvalidRequestError, typeof import("@opencode-ai/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
5
  readonly id: import("effect/Schema").brand<import("effect/Schema").String, "Event.ID"> & {
6
6
  create: () => string & import("effect/Brand").Brand<"Event.ID">;
7
7
  };
package/dist/fetch.d.ts CHANGED
@@ -59,6 +59,7 @@ export declare const make: (options?: {
59
59
  readonly gitbash?: string | undefined;
60
60
  } | undefined;
61
61
  readonly port?: number | undefined;
62
+ readonly cors?: readonly string[] | undefined;
62
63
  readonly password?: string | undefined;
63
64
  readonly app?: {
64
65
  readonly version?: string | undefined;
package/dist/fetch.js CHANGED
@@ -7,5 +7,5 @@ import { createRoutes } from "./routes";
7
7
  export const make = Effect.fn("ServerFetch.make")(function* (options = {}, boot = {}) {
8
8
  const context = yield* Layer.build(createRoutes(options, () => [], boot.overrides ?? []).pipe(Layer.provide(HttpServer.layerServices)));
9
9
  yield* Effect.forkDetach(Context.get(context, SessionRestart.Service).resumeSuspendedSessions);
10
- return Context.get(context, HttpRouter.HttpRouter).asHttpEffect().pipe(HttpMiddleware.cors({ allowedOrigins: isAllowedCorsOrigin, maxAge: 86400 }), HttpEffect.toWebHandlerWith(context));
10
+ return Context.get(context, HttpRouter.HttpRouter).asHttpEffect().pipe(HttpMiddleware.cors({ allowedOrigins: (origin) => isAllowedCorsOrigin(origin, options), maxAge: 86400 }), HttpEffect.toWebHandlerWith(context));
11
11
  });
@@ -1 +1,3 @@
1
- export declare const FormHandler: import("effect/Layer").Layer<import("effect/unstable/httpapi/HttpApiGroup").Service<"server", "server.form">, never, import("../location").LocationMiddleware | (import("@opencode-ai/protocol/middleware/schema-error").SchemaErrorMiddleware | import("@opencode-ai/protocol/middleware/authorization").Authorization | import("../middleware/form-location").FormLocationMiddleware)>;
1
+ import { Database } from "@opencode-ai/core/database/database";
2
+ import { LocationServiceMap } from "@opencode-ai/core/location-services";
3
+ export declare const FormHandler: import("effect/Layer").Layer<import("effect/unstable/httpapi/HttpApiGroup").Service<"server", "server.form">, never, Database.Service | LocationServiceMap.Service | import("../location").LocationMiddleware | (import("@opencode-ai/protocol/middleware/schema-error").SchemaErrorMiddleware | import("@opencode-ai/protocol/middleware/authorization").Authorization | import("../middleware/form-location").FormLocationMiddleware)>;
@@ -1,4 +1,6 @@
1
+ import { Database } from "@opencode-ai/core/database/database";
1
2
  import { Form } from "@opencode-ai/core/form";
3
+ import { LocationServiceMap } from "@opencode-ai/core/location-services";
2
4
  import {
3
5
  ConflictError,
4
6
  FormAlreadySettledError,
@@ -6,15 +8,15 @@ import {
6
8
  FormNotFoundError,
7
9
  InvalidRequestError
8
10
  } from "@opencode-ai/protocol/errors";
9
- import { Effect } from "effect";
11
+ import { Effect, Option } from "effect";
10
12
  import { HttpApiBuilder, HttpApiSchema } from "effect/unstable/httpapi";
11
13
  import { Api } from "../api";
12
- import { response } from "../location";
14
+ import { requestRef, response, sessionRef, withLoadedLocationServices } from "../location";
13
15
  function missingForm(id) {
14
16
  return new FormNotFoundError({ id, message: `Form not found: ${id}` });
15
17
  }
16
18
  export const FormHandler = HttpApiBuilder.group(Api, "server.form", (handlers) => Effect.gen(function* () {
17
- const requireOwnedForm = Effect.fnUntraced(function* (sessionID, formID) {
19
+ const locations = yield* LocationServiceMap.Service, database = yield* Database.Service, requireOwnedForm = Effect.fnUntraced(function* (sessionID, formID) {
18
20
  const form = yield* Form.Service, info = yield* form.get(formID).pipe(Effect.catchTag("Form.NotFoundError", () => missingForm(formID)));
19
21
  if (info.sessionID !== sessionID)
20
22
  return yield* missingForm(formID);
@@ -24,7 +26,8 @@ export const FormHandler = HttpApiBuilder.group(Api, "server.form", (handlers) =
24
26
  const form = yield* Form.Service;
25
27
  return yield* response(form.list());
26
28
  })).handle("session.form.list", Effect.fn(function* (ctx) {
27
- return { data: yield* (yield* Form.Service).list({ sessionID: ctx.params.sessionID }) };
29
+ const ref = ctx.params.sessionID === "global" ? requestRef(ctx.request) : yield* sessionRef(database, ctx.params.sessionID), forms = yield* withLoadedLocationServices(locations, ref, Form.Service.use((form) => form.list({ sessionID: ctx.params.sessionID })));
30
+ return { data: Option.getOrElse(forms, () => []) };
28
31
  })).handle("session.form.create", Effect.fn(function* (ctx) {
29
32
  return { data: yield* (yield* Form.Service).create({
30
33
  id: ctx.payload.id,
@@ -1,2 +1,4 @@
1
+ import { Database } from "@opencode-ai/core/database/database";
2
+ import { LocationServiceMap } from "@opencode-ai/core/location-services";
1
3
  import { PermissionSaved } from "@opencode-ai/core/permission/saved";
2
- export declare const PermissionHandler: import("effect/Layer").Layer<import("effect/unstable/httpapi/HttpApiGroup").Service<"server", "server.permission">, never, import("../middleware/session-location").SessionLocationMiddleware | (import("@opencode-ai/protocol/middleware/schema-error").SchemaErrorMiddleware | import("@opencode-ai/protocol/middleware/authorization").Authorization | import("../location").LocationMiddleware | import("effect/unstable/http/HttpRouter").Request<"Requires", PermissionSaved.Service>)>;
4
+ export declare const PermissionHandler: import("effect/Layer").Layer<import("effect/unstable/httpapi/HttpApiGroup").Service<"server", "server.permission">, never, Database.Service | LocationServiceMap.Service | import("../middleware/session-location").SessionLocationMiddleware | (import("@opencode-ai/protocol/middleware/schema-error").SchemaErrorMiddleware | import("@opencode-ai/protocol/middleware/authorization").Authorization | import("../location").LocationMiddleware | import("effect/unstable/http/HttpRouter").Request<"Requires", PermissionSaved.Service>)>;
@@ -1,16 +1,18 @@
1
+ import { Database } from "@opencode-ai/core/database/database";
1
2
  import { Location } from "@opencode-ai/core/location";
3
+ import { LocationServiceMap } from "@opencode-ai/core/location-services";
2
4
  import { Permission } from "@opencode-ai/core/permission";
3
5
  import { PermissionSaved } from "@opencode-ai/core/permission/saved";
4
- import { Effect } from "effect";
6
+ import { Effect, Option } from "effect";
5
7
  import { HttpApiBuilder, HttpApiSchema } from "effect/unstable/httpapi";
6
8
  import { Api } from "../api";
7
9
  import { PermissionNotFoundError, SessionNotFoundError } from "@opencode-ai/protocol/errors";
8
- import { response } from "../location";
10
+ import { response, sessionRef, withLoadedLocationServices } from "../location";
9
11
  function missingRequest(id) {
10
12
  return new PermissionNotFoundError({ requestID: id, message: `Permission request not found: ${id}` });
11
13
  }
12
14
  export const PermissionHandler = HttpApiBuilder.group(Api, "server.permission", (handlers) => Effect.gen(function* () {
13
- const requireOwnedRequest = Effect.fnUntraced(function* (sessionID, requestID) {
15
+ const locations = yield* LocationServiceMap.Service, database = yield* Database.Service, requireOwnedRequest = Effect.fnUntraced(function* (sessionID, requestID) {
14
16
  const permission = yield* Permission.Service, request = yield* permission.get(requestID);
15
17
  if (!request || request.sessionID !== sessionID)
16
18
  return yield* missingRequest(requestID);
@@ -36,7 +38,8 @@ export const PermissionHandler = HttpApiBuilder.group(Api, "server.permission",
36
38
  })))
37
39
  };
38
40
  })).handle("session.permission.list", Effect.fn(function* (ctx) {
39
- return { data: yield* (yield* Permission.Service).forSession(ctx.params.sessionID) };
41
+ const ref = yield* sessionRef(database, ctx.params.sessionID), requests = yield* withLoadedLocationServices(locations, ref, Permission.Service.use((permission) => permission.forSession(ctx.params.sessionID)));
42
+ return { data: Option.getOrElse(requests, () => []) };
40
43
  })).handle("session.permission.get", Effect.fn(function* (ctx) {
41
44
  return { data: (yield* requireOwnedRequest(ctx.params.sessionID, ctx.params.requestID)).request };
42
45
  })).handle("session.permission.reply", Effect.fn(function* (ctx) {
@@ -1,16 +1,23 @@
1
1
  import { Vcs } from "@opencode-ai/core/vcs";
2
+ import { ServiceUnavailableError } from "@opencode-ai/protocol/errors";
2
3
  import { Effect } from "effect";
3
4
  import { HttpApiBuilder } from "effect/unstable/httpapi";
4
5
  import { Api } from "../api";
5
6
  import { response } from "../location";
7
+ import { pluginReadiness } from "./plugin-readiness";
8
+ const flushPlugins = pluginReadiness(() => new ServiceUnavailableError({ service: "vcs", message: "VCS initialization timed out" }));
6
9
  export const VcsHandler = HttpApiBuilder.group(Api, "server.vcs", (handlers) => Effect.gen(function* () {
7
10
  return handlers.handle("vcs.get", () => response(Effect.gen(function* () {
8
11
  return yield* (yield* Vcs.Service).info();
12
+ }))).handle("vcs.base", () => response(Effect.gen(function* () {
13
+ yield* flushPlugins;
14
+ return yield* (yield* Vcs.Service).base().pipe(Effect.mapError((error) => new ServiceUnavailableError({ service: "vcs", message: error.message })));
9
15
  }))).handle("vcs.status", () => response(Effect.gen(function* () {
10
16
  return yield* (yield* Vcs.Service).status();
11
17
  }))).handle("vcs.branches", (ctx) => response(Effect.gen(function* () {
12
18
  return yield* (yield* Vcs.Service).branches({ search: ctx.query.search, limit: Math.min(ctx.query.limit ?? 50, 100) });
13
19
  }))).handle("vcs.diff", (ctx) => response(Effect.gen(function* () {
14
- return yield* (yield* Vcs.Service).diff(ctx.query.mode, { context: ctx.query.context });
20
+ yield* flushPlugins;
21
+ 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 })));
15
22
  })));
16
23
  }));
@@ -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.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.health"> | 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"> | import("effect/unstable/httpapi/HttpApiGroup").Service<"server", "server.workspace">, never, import("@opencode-ai/protocol/middleware/schema-error").SchemaErrorMiddleware | import("@opencode-ai/protocol/middleware/authorization").Authorization | import("@opencode-ai/util/global").Service | import("@opencode-ai/core/bus").Service | import("@opencode-ai/core/workspace").Service | import("@opencode-ai/core/worktree").Service | import("@opencode-ai/core/location-service-map").Service | import("@opencode-ai/core/persistent-pty/index").Service | import("@opencode-ai/core/session").Service | import("./location").LocationMiddleware | import("./middleware/form-location").FormLocationMiddleware | import("./middleware/session-location").SessionLocationMiddleware | import("@opencode-ai/core/pty/ticket").Service | import("@opencode-ai/core/session/transfer").Service | import("effect/unstable/http/HttpRouter").Request<"Requires", import("@opencode-ai/core/database/database").Service> | import("effect/unstable/http/HttpRouter").Request<"Requires", import("@opencode-ai/core/permission/saved").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-ai/core/wellknown").Service> | import("effect/unstable/http/HttpRouter").Request<"Requires", import("@opencode-ai/core/project").Service>>;
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.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.health"> | 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"> | import("effect/unstable/httpapi/HttpApiGroup").Service<"server", "server.workspace">, never, import("@opencode-ai/protocol/middleware/schema-error").SchemaErrorMiddleware | import("@opencode-ai/protocol/middleware/authorization").Authorization | import("@opencode-ai/util/global").Service | import("@opencode-ai/core/database/database").Service | import("@opencode-ai/core/bus").Service | import("@opencode-ai/core/workspace").Service | import("@opencode-ai/core/location-service-map").Service | import("@opencode-ai/core/worktree").Service | import("@opencode-ai/core/session").Service | import("@opencode-ai/core/persistent-pty/index").Service | import("./location").LocationMiddleware | import("./middleware/form-location").FormLocationMiddleware | import("./middleware/session-location").SessionLocationMiddleware | import("@opencode-ai/core/pty/ticket").Service | import("@opencode-ai/core/session/transfer").Service | import("effect/unstable/http/HttpRouter").Request<"Requires", import("@opencode-ai/core/database/database").Service> | import("effect/unstable/http/HttpRouter").Request<"Requires", import("@opencode-ai/core/permission/saved").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-ai/core/wellknown").Service> | import("effect/unstable/http/HttpRouter").Request<"Requires", import("@opencode-ai/core/project").Service>>;
@@ -1,23 +1,30 @@
1
+ import { Database } from "@opencode-ai/core/database/database";
1
2
  import { Location } from "@opencode-ai/core/location";
2
3
  import { LocationServiceMap } from "@opencode-ai/core/location-services";
3
- import { Effect, Layer } from "effect";
4
+ import { InvalidRequestError, SessionNotFoundError } from "@opencode-ai/protocol/errors";
5
+ import { Context, Effect, Layer, Option } from "effect";
4
6
  import { HttpServerRequest } from "effect/unstable/http";
5
7
  import { HttpApiMiddleware } from "effect/unstable/httpapi";
6
8
  export type LocationServices = Layer.Success<ReturnType<(typeof LocationServiceMap.Service)["get"]>>;
7
9
  declare const LocationMiddleware_base: HttpApiMiddleware.ServiceClass<LocationMiddleware, "@opencode/HttpApiLocation", {
8
10
  requires: never;
9
- provides: Location.Service | import("@opencode-ai/core/config").Service | import("@opencode-ai/core/agent").Service | import("@opencode-ai/core/aisdk").Service | import("@opencode-ai/core/form").Service | import("@opencode-ai/core/integration").Service | import("@opencode-ai/core/catalog").Service | import("@opencode-ai/core/command").Service | import("@opencode-ai/core/environment/environment").Service | import("@opencode-ai/core/mcp/index").Service | import("@opencode-ai/core/file-mutation").Service | import("@opencode-ai/core/formatter").Service | import("@opencode-ai/core/filesystem/search").Service | import("@opencode-ai/core/filesystem").Service | import("@opencode-ai/core/model-resolver").Service | import("@opencode-ai/core/generate").Service | import("@opencode-ai/core/image").Service | import("@opencode-ai/core/plugin/supervisor-service").Service | import("@opencode-ai/core/plugin/instance").Service | import("@opencode-ai/core/plugin/hooks").Service | import("@opencode-ai/core/permission").Service | import("@opencode-ai/core/location-mutation").Service | import("@opencode-ai/core/session/instructions").Service | import("@opencode-ai/core/tool/read-filesystem").Service | import("@opencode-ai/core/shell/select").Service | import("@opencode-ai/core/instruction-discovery").Service | import("@opencode-ai/core/instructions/builtins").Service | import("@opencode-ai/core/tool").Service | import("@opencode-ai/core/tool/mcp").Service | import("@opencode-ai/core/reference").Service | import("@opencode-ai/core/reference/instructions").Service | import("@opencode-ai/core/skill").Service | import("@opencode-ai/core/skill/instructions").Service | import("@opencode-ai/core/session/instruction-entry").Service | import("@opencode-ai/core/session/model-transport").Service | import("@opencode-ai/core/session/runner/model").Service | import("@opencode-ai/core/plugin").Service | import("@opencode-ai/core/shell").Service | import("@opencode-ai/core/websearch").Service | import("@opencode-ai/core/session/compaction").Service | import("@opencode-ai/core/snapshot").Service | import("@opencode-ai/core/tool-output").Service | import("@opencode-ai/core/vcs").Service | import("@opencode-ai/core/filesystem/location-watcher").Service | import("@opencode-ai/core/pty").Service | import("@opencode-ai/core/session/title").Service | import("@opencode-ai/core/session/runner/index").Service | import("@opencode-ai/core/session/generate").Service;
11
+ provides: Location.Service | import("@opencode-ai/core/config").Service | import("@opencode-ai/core/agent").Service | import("@opencode-ai/core/aisdk").Service | import("@opencode-ai/core/form").Service | import("@opencode-ai/core/integration").Service | import("@opencode-ai/core/catalog").Service | import("@opencode-ai/core/command").Service | import("@opencode-ai/core/environment/environment").Service | import("@opencode-ai/core/mcp/index").Service | import("@opencode-ai/core/file-mutation").Service | import("@opencode-ai/core/formatter").Service | import("@opencode-ai/core/filesystem/search").Service | import("@opencode-ai/core/filesystem").Service | import("@opencode-ai/core/model-resolver").Service | import("@opencode-ai/core/generate").Service | import("@opencode-ai/core/image").Service | import("@opencode-ai/core/plugin/supervisor-service").Service | import("@opencode-ai/core/plugin/instance").Service | import("@opencode-ai/core/plugin/hooks").Service | import("@opencode-ai/core/permission").Service | import("@opencode-ai/core/location-mutation").Service | import("@opencode-ai/core/session/instructions").Service | import("@opencode-ai/core/tool/read-filesystem").Service | import("@opencode-ai/core/shell/select").Service | import("@opencode-ai/core/instruction-discovery").Service | import("@opencode-ai/core/instructions/builtins").Service | import("@opencode-ai/core/tool").Service | import("@opencode-ai/core/tool/mcp").Service | import("@opencode-ai/core/reference").Service | import("@opencode-ai/core/reference/instructions").Service | import("@opencode-ai/core/skill").Service | import("@opencode-ai/core/skill/instructions").Service | import("@opencode-ai/core/session/instruction-entry").Service | import("@opencode-ai/core/session/model-transport").Service | import("@opencode-ai/core/session/runner/model").Service | import("@opencode-ai/core/plugin").Service | import("@opencode-ai/core/shell").Service | import("@opencode-ai/core/session/prompt").Service | import("@opencode-ai/core/session/revert").Service | import("@opencode-ai/core/websearch").Service | import("@opencode-ai/core/session/compaction").Service | import("@opencode-ai/core/snapshot").Service | import("@opencode-ai/core/tool-output").Service | import("@opencode-ai/core/vcs").Service | import("@opencode-ai/core/session/runner/index").Service | import("@opencode-ai/core/pty").Service | import("@opencode-ai/core/session/generate").Service | import("@opencode-ai/core/session/title").Service | import("@opencode-ai/core/filesystem/location-watcher").Service;
10
12
  error: never;
11
13
  clientError: never;
12
14
  requiredForClient: false;
13
15
  security: never;
14
- }, HttpApiMiddleware.HttpApiMiddleware<Location.Service | import("@opencode-ai/core/config").Service | import("@opencode-ai/core/agent").Service | import("@opencode-ai/core/aisdk").Service | import("@opencode-ai/core/form").Service | import("@opencode-ai/core/integration").Service | import("@opencode-ai/core/catalog").Service | import("@opencode-ai/core/command").Service | import("@opencode-ai/core/environment/environment").Service | import("@opencode-ai/core/mcp/index").Service | import("@opencode-ai/core/file-mutation").Service | import("@opencode-ai/core/formatter").Service | import("@opencode-ai/core/filesystem/search").Service | import("@opencode-ai/core/filesystem").Service | import("@opencode-ai/core/model-resolver").Service | import("@opencode-ai/core/generate").Service | import("@opencode-ai/core/image").Service | import("@opencode-ai/core/plugin/supervisor-service").Service | import("@opencode-ai/core/plugin/instance").Service | import("@opencode-ai/core/plugin/hooks").Service | import("@opencode-ai/core/permission").Service | import("@opencode-ai/core/location-mutation").Service | import("@opencode-ai/core/session/instructions").Service | import("@opencode-ai/core/tool/read-filesystem").Service | import("@opencode-ai/core/shell/select").Service | import("@opencode-ai/core/instruction-discovery").Service | import("@opencode-ai/core/instructions/builtins").Service | import("@opencode-ai/core/tool").Service | import("@opencode-ai/core/tool/mcp").Service | import("@opencode-ai/core/reference").Service | import("@opencode-ai/core/reference/instructions").Service | import("@opencode-ai/core/skill").Service | import("@opencode-ai/core/skill/instructions").Service | import("@opencode-ai/core/session/instruction-entry").Service | import("@opencode-ai/core/session/model-transport").Service | import("@opencode-ai/core/session/runner/model").Service | import("@opencode-ai/core/plugin").Service | import("@opencode-ai/core/shell").Service | import("@opencode-ai/core/websearch").Service | import("@opencode-ai/core/session/compaction").Service | import("@opencode-ai/core/snapshot").Service | import("@opencode-ai/core/tool-output").Service | import("@opencode-ai/core/vcs").Service | import("@opencode-ai/core/filesystem/location-watcher").Service | import("@opencode-ai/core/pty").Service | import("@opencode-ai/core/session/title").Service | import("@opencode-ai/core/session/runner/index").Service | import("@opencode-ai/core/session/generate").Service, never, never>>;
16
+ }, HttpApiMiddleware.HttpApiMiddleware<Location.Service | import("@opencode-ai/core/config").Service | import("@opencode-ai/core/agent").Service | import("@opencode-ai/core/aisdk").Service | import("@opencode-ai/core/form").Service | import("@opencode-ai/core/integration").Service | import("@opencode-ai/core/catalog").Service | import("@opencode-ai/core/command").Service | import("@opencode-ai/core/environment/environment").Service | import("@opencode-ai/core/mcp/index").Service | import("@opencode-ai/core/file-mutation").Service | import("@opencode-ai/core/formatter").Service | import("@opencode-ai/core/filesystem/search").Service | import("@opencode-ai/core/filesystem").Service | import("@opencode-ai/core/model-resolver").Service | import("@opencode-ai/core/generate").Service | import("@opencode-ai/core/image").Service | import("@opencode-ai/core/plugin/supervisor-service").Service | import("@opencode-ai/core/plugin/instance").Service | import("@opencode-ai/core/plugin/hooks").Service | import("@opencode-ai/core/permission").Service | import("@opencode-ai/core/location-mutation").Service | import("@opencode-ai/core/session/instructions").Service | import("@opencode-ai/core/tool/read-filesystem").Service | import("@opencode-ai/core/shell/select").Service | import("@opencode-ai/core/instruction-discovery").Service | import("@opencode-ai/core/instructions/builtins").Service | import("@opencode-ai/core/tool").Service | import("@opencode-ai/core/tool/mcp").Service | import("@opencode-ai/core/reference").Service | import("@opencode-ai/core/reference/instructions").Service | import("@opencode-ai/core/skill").Service | import("@opencode-ai/core/skill/instructions").Service | import("@opencode-ai/core/session/instruction-entry").Service | import("@opencode-ai/core/session/model-transport").Service | import("@opencode-ai/core/session/runner/model").Service | import("@opencode-ai/core/plugin").Service | import("@opencode-ai/core/shell").Service | import("@opencode-ai/core/session/prompt").Service | import("@opencode-ai/core/session/revert").Service | import("@opencode-ai/core/websearch").Service | import("@opencode-ai/core/session/compaction").Service | import("@opencode-ai/core/snapshot").Service | import("@opencode-ai/core/tool-output").Service | import("@opencode-ai/core/vcs").Service | import("@opencode-ai/core/session/runner/index").Service | import("@opencode-ai/core/pty").Service | import("@opencode-ai/core/session/generate").Service | import("@opencode-ai/core/session/title").Service | import("@opencode-ai/core/filesystem/location-watcher").Service, never, never>>;
15
17
  export declare class LocationMiddleware extends LocationMiddleware_base {
16
18
  }
17
19
  export declare function response<A, E, R>(data: Effect.Effect<A, E, R>): Effect.Effect<{
18
20
  location: Location.Info;
19
21
  data: A;
20
22
  }, E, Location.Service | R>;
23
+ export declare function sessionRef(database: Context.Service.Shape<typeof Database.Service>, sessionID: unknown): Effect.Effect<{
24
+ readonly directory: string & import("effect/Brand").Brand<"AbsolutePath">;
25
+ readonly workspaceID?: (string & import("effect/Brand").Brand<"Workspace.ID">) | undefined;
26
+ }, InvalidRequestError | SessionNotFoundError, never>;
27
+ export declare function withLoadedLocationServices<A, E>(locations: Context.Service.Shape<typeof LocationServiceMap.Service>, ref: Location.Ref, effect: Effect.Effect<A, E, LocationServices>): Effect.Effect<Option.Option<A>, E, never>;
21
28
  export declare function requestRef(request: HttpServerRequest.HttpServerRequest): Location.Ref;
22
29
  export declare const layer: Layer.Layer<LocationMiddleware, never, LocationServiceMap.Service>;
23
30
  export {};
package/dist/location.js CHANGED
@@ -1,8 +1,13 @@
1
+ import { Database } from "@opencode-ai/core/database/database";
1
2
  import { Location } from "@opencode-ai/core/location";
2
3
  import { LocationServiceMap } from "@opencode-ai/core/location-services";
3
4
  import { AbsolutePath } from "@opencode-ai/core/schema";
5
+ import { Session } from "@opencode-ai/core/session";
6
+ import { SessionTable } from "@opencode-ai/core/session/sql";
4
7
  import { Workspace } from "@opencode-ai/core/workspace";
5
- import { Effect, Layer } from "effect";
8
+ import { InvalidRequestError, SessionNotFoundError } from "@opencode-ai/protocol/errors";
9
+ import { eq } from "drizzle-orm";
10
+ import { Context, Effect, Layer, Option, Schema } from "effect";
6
11
  import { HttpServerRequest } from "effect/unstable/http";
7
12
  import { HttpApiMiddleware } from "effect/unstable/httpapi";
8
13
 
@@ -21,6 +26,26 @@ export function response(data) {
21
26
  };
22
27
  });
23
28
  }
29
+ const decodeSessionID = Schema.decodeUnknownEffect(Session.ID);
30
+ export function sessionRef(database, sessionID) {
31
+ return Effect.gen(function* () {
32
+ const id = yield* decodeSessionID(sessionID).pipe(Effect.mapError(() => new InvalidRequestError({ message: "Invalid session ID", field: "sessionID" }))), row = yield* database.db.select({ directory: SessionTable.directory, workspaceID: SessionTable.workspace_id }).from(SessionTable).where(eq(SessionTable.id, id)).get().pipe(Effect.orDie);
33
+ if (!row)
34
+ return yield* new SessionNotFoundError({ sessionID: id, message: `Session not found: ${id}` });
35
+ return Location.Ref.make({
36
+ directory: AbsolutePath.make(row.directory),
37
+ workspaceID: row.workspaceID ? Workspace.ID.make(row.workspaceID) : void 0
38
+ });
39
+ });
40
+ }
41
+ export function withLoadedLocationServices(locations, ref, effect) {
42
+ return Effect.scoped(Effect.gen(function* () {
43
+ const context = yield* locations.contextEffectOption(ref);
44
+ if (Option.isNone(context))
45
+ return Option.none();
46
+ return Option.some(yield* effect.pipe(Effect.provide(context.value)));
47
+ }));
48
+ }
24
49
  export function requestRef(request) {
25
50
  const query = new URL(request.url, "http://localhost").searchParams, workspaceID = query.get("location[workspace]") || request.headers["x-opencode-workspace"], directory = query.get("location[directory]") || (request.headers["x-opencode-directory"] ? decode(request.headers["x-opencode-directory"]) : process.cwd());
26
51
  return Location.Ref.make({
@@ -1,17 +1,16 @@
1
1
  import { Database } from "@opencode-ai/core/database/database";
2
- import { Location } from "@opencode-ai/core/location";
3
2
  import { LocationServiceMap } from "@opencode-ai/core/location-services";
4
3
  import { InvalidRequestError, SessionNotFoundError } from "@opencode-ai/protocol/errors";
5
4
  import { Layer } from "effect";
6
5
  import { HttpApiMiddleware } from "effect/unstable/httpapi";
7
6
  declare const FormLocationMiddleware_base: HttpApiMiddleware.ServiceClass<FormLocationMiddleware, "@opencode/HttpApiFormLocation", {
8
7
  requires: never;
9
- provides: Location.Service | import("@opencode-ai/core/config").Service | import("@opencode-ai/core/agent").Service | import("@opencode-ai/core/aisdk").Service | import("@opencode-ai/core/form").Service | import("@opencode-ai/core/integration").Service | import("@opencode-ai/core/catalog").Service | import("@opencode-ai/core/command").Service | import("@opencode-ai/core/environment/environment").Service | import("@opencode-ai/core/mcp/index").Service | import("@opencode-ai/core/file-mutation").Service | import("@opencode-ai/core/formatter").Service | import("@opencode-ai/core/filesystem/search").Service | import("@opencode-ai/core/filesystem").Service | import("@opencode-ai/core/model-resolver").Service | import("@opencode-ai/core/generate").Service | import("@opencode-ai/core/image").Service | import("@opencode-ai/core/plugin/supervisor-service").Service | import("@opencode-ai/core/plugin/instance").Service | import("@opencode-ai/core/plugin/hooks").Service | import("@opencode-ai/core/permission").Service | import("@opencode-ai/core/location-mutation").Service | import("@opencode-ai/core/session/instructions").Service | import("@opencode-ai/core/tool/read-filesystem").Service | import("@opencode-ai/core/shell/select").Service | import("@opencode-ai/core/instruction-discovery").Service | import("@opencode-ai/core/instructions/builtins").Service | import("@opencode-ai/core/tool").Service | import("@opencode-ai/core/tool/mcp").Service | import("@opencode-ai/core/reference").Service | import("@opencode-ai/core/reference/instructions").Service | import("@opencode-ai/core/skill").Service | import("@opencode-ai/core/skill/instructions").Service | import("@opencode-ai/core/session/instruction-entry").Service | import("@opencode-ai/core/session/model-transport").Service | import("@opencode-ai/core/session/runner/model").Service | import("@opencode-ai/core/plugin").Service | import("@opencode-ai/core/shell").Service | import("@opencode-ai/core/websearch").Service | import("@opencode-ai/core/session/compaction").Service | import("@opencode-ai/core/snapshot").Service | import("@opencode-ai/core/tool-output").Service | import("@opencode-ai/core/vcs").Service | import("@opencode-ai/core/filesystem/location-watcher").Service | import("@opencode-ai/core/pty").Service | import("@opencode-ai/core/session/title").Service | import("@opencode-ai/core/session/runner/index").Service | import("@opencode-ai/core/session/generate").Service;
8
+ provides: import("@opencode-ai/core/location").Service | import("@opencode-ai/core/config").Service | import("@opencode-ai/core/agent").Service | import("@opencode-ai/core/aisdk").Service | import("@opencode-ai/core/form").Service | import("@opencode-ai/core/integration").Service | import("@opencode-ai/core/catalog").Service | import("@opencode-ai/core/command").Service | import("@opencode-ai/core/environment/environment").Service | import("@opencode-ai/core/mcp/index").Service | import("@opencode-ai/core/file-mutation").Service | import("@opencode-ai/core/formatter").Service | import("@opencode-ai/core/filesystem/search").Service | import("@opencode-ai/core/filesystem").Service | import("@opencode-ai/core/model-resolver").Service | import("@opencode-ai/core/generate").Service | import("@opencode-ai/core/image").Service | import("@opencode-ai/core/plugin/supervisor-service").Service | import("@opencode-ai/core/plugin/instance").Service | import("@opencode-ai/core/plugin/hooks").Service | import("@opencode-ai/core/permission").Service | import("@opencode-ai/core/location-mutation").Service | import("@opencode-ai/core/session/instructions").Service | import("@opencode-ai/core/tool/read-filesystem").Service | import("@opencode-ai/core/shell/select").Service | import("@opencode-ai/core/instruction-discovery").Service | import("@opencode-ai/core/instructions/builtins").Service | import("@opencode-ai/core/tool").Service | import("@opencode-ai/core/tool/mcp").Service | import("@opencode-ai/core/reference").Service | import("@opencode-ai/core/reference/instructions").Service | import("@opencode-ai/core/skill").Service | import("@opencode-ai/core/skill/instructions").Service | import("@opencode-ai/core/session/instruction-entry").Service | import("@opencode-ai/core/session/model-transport").Service | import("@opencode-ai/core/session/runner/model").Service | import("@opencode-ai/core/plugin").Service | import("@opencode-ai/core/shell").Service | import("@opencode-ai/core/session/prompt").Service | import("@opencode-ai/core/session/revert").Service | import("@opencode-ai/core/websearch").Service | import("@opencode-ai/core/session/compaction").Service | import("@opencode-ai/core/snapshot").Service | import("@opencode-ai/core/tool-output").Service | import("@opencode-ai/core/vcs").Service | import("@opencode-ai/core/session/runner/index").Service | import("@opencode-ai/core/pty").Service | import("@opencode-ai/core/session/generate").Service | import("@opencode-ai/core/session/title").Service | import("@opencode-ai/core/filesystem/location-watcher").Service;
10
9
  error: readonly [typeof InvalidRequestError, typeof SessionNotFoundError];
11
10
  clientError: never;
12
11
  requiredForClient: false;
13
12
  security: never;
14
- }, HttpApiMiddleware.HttpApiMiddleware<Location.Service | import("@opencode-ai/core/config").Service | import("@opencode-ai/core/agent").Service | import("@opencode-ai/core/aisdk").Service | import("@opencode-ai/core/form").Service | import("@opencode-ai/core/integration").Service | import("@opencode-ai/core/catalog").Service | import("@opencode-ai/core/command").Service | import("@opencode-ai/core/environment/environment").Service | import("@opencode-ai/core/mcp/index").Service | import("@opencode-ai/core/file-mutation").Service | import("@opencode-ai/core/formatter").Service | import("@opencode-ai/core/filesystem/search").Service | import("@opencode-ai/core/filesystem").Service | import("@opencode-ai/core/model-resolver").Service | import("@opencode-ai/core/generate").Service | import("@opencode-ai/core/image").Service | import("@opencode-ai/core/plugin/supervisor-service").Service | import("@opencode-ai/core/plugin/instance").Service | import("@opencode-ai/core/plugin/hooks").Service | import("@opencode-ai/core/permission").Service | import("@opencode-ai/core/location-mutation").Service | import("@opencode-ai/core/session/instructions").Service | import("@opencode-ai/core/tool/read-filesystem").Service | import("@opencode-ai/core/shell/select").Service | import("@opencode-ai/core/instruction-discovery").Service | import("@opencode-ai/core/instructions/builtins").Service | import("@opencode-ai/core/tool").Service | import("@opencode-ai/core/tool/mcp").Service | import("@opencode-ai/core/reference").Service | import("@opencode-ai/core/reference/instructions").Service | import("@opencode-ai/core/skill").Service | import("@opencode-ai/core/skill/instructions").Service | import("@opencode-ai/core/session/instruction-entry").Service | import("@opencode-ai/core/session/model-transport").Service | import("@opencode-ai/core/session/runner/model").Service | import("@opencode-ai/core/plugin").Service | import("@opencode-ai/core/shell").Service | import("@opencode-ai/core/websearch").Service | import("@opencode-ai/core/session/compaction").Service | import("@opencode-ai/core/snapshot").Service | import("@opencode-ai/core/tool-output").Service | import("@opencode-ai/core/vcs").Service | import("@opencode-ai/core/filesystem/location-watcher").Service | import("@opencode-ai/core/pty").Service | import("@opencode-ai/core/session/title").Service | import("@opencode-ai/core/session/runner/index").Service | import("@opencode-ai/core/session/generate").Service, readonly [typeof InvalidRequestError, typeof SessionNotFoundError], never>>;
13
+ }, HttpApiMiddleware.HttpApiMiddleware<import("@opencode-ai/core/location").Service | import("@opencode-ai/core/config").Service | import("@opencode-ai/core/agent").Service | import("@opencode-ai/core/aisdk").Service | import("@opencode-ai/core/form").Service | import("@opencode-ai/core/integration").Service | import("@opencode-ai/core/catalog").Service | import("@opencode-ai/core/command").Service | import("@opencode-ai/core/environment/environment").Service | import("@opencode-ai/core/mcp/index").Service | import("@opencode-ai/core/file-mutation").Service | import("@opencode-ai/core/formatter").Service | import("@opencode-ai/core/filesystem/search").Service | import("@opencode-ai/core/filesystem").Service | import("@opencode-ai/core/model-resolver").Service | import("@opencode-ai/core/generate").Service | import("@opencode-ai/core/image").Service | import("@opencode-ai/core/plugin/supervisor-service").Service | import("@opencode-ai/core/plugin/instance").Service | import("@opencode-ai/core/plugin/hooks").Service | import("@opencode-ai/core/permission").Service | import("@opencode-ai/core/location-mutation").Service | import("@opencode-ai/core/session/instructions").Service | import("@opencode-ai/core/tool/read-filesystem").Service | import("@opencode-ai/core/shell/select").Service | import("@opencode-ai/core/instruction-discovery").Service | import("@opencode-ai/core/instructions/builtins").Service | import("@opencode-ai/core/tool").Service | import("@opencode-ai/core/tool/mcp").Service | import("@opencode-ai/core/reference").Service | import("@opencode-ai/core/reference/instructions").Service | import("@opencode-ai/core/skill").Service | import("@opencode-ai/core/skill/instructions").Service | import("@opencode-ai/core/session/instruction-entry").Service | import("@opencode-ai/core/session/model-transport").Service | import("@opencode-ai/core/session/runner/model").Service | import("@opencode-ai/core/plugin").Service | import("@opencode-ai/core/shell").Service | import("@opencode-ai/core/session/prompt").Service | import("@opencode-ai/core/session/revert").Service | import("@opencode-ai/core/websearch").Service | import("@opencode-ai/core/session/compaction").Service | import("@opencode-ai/core/snapshot").Service | import("@opencode-ai/core/tool-output").Service | import("@opencode-ai/core/vcs").Service | import("@opencode-ai/core/session/runner/index").Service | import("@opencode-ai/core/pty").Service | import("@opencode-ai/core/session/generate").Service | import("@opencode-ai/core/session/title").Service | import("@opencode-ai/core/filesystem/location-watcher").Service, readonly [typeof InvalidRequestError, typeof SessionNotFoundError], never>>;
15
14
  export declare class FormLocationMiddleware extends FormLocationMiddleware_base {
16
15
  }
17
16
  export declare const formLocationLayer: Layer.Layer<FormLocationMiddleware, never, Database.Service | LocationServiceMap.Service>;
@@ -1,42 +1,24 @@
1
1
  import { Database } from "@opencode-ai/core/database/database";
2
- import { Location } from "@opencode-ai/core/location";
3
2
  import { LocationServiceMap } from "@opencode-ai/core/location-services";
4
- import { AbsolutePath } from "@opencode-ai/core/schema";
5
- import { Session } from "@opencode-ai/core/session";
6
- import { SessionTable } from "@opencode-ai/core/session/sql";
7
- import { Workspace } from "@opencode-ai/core/workspace";
8
3
  import { InvalidRequestError, SessionNotFoundError } from "@opencode-ai/protocol/errors";
9
- import { eq } from "drizzle-orm";
10
- import { Effect, Layer, Schema } from "effect";
4
+ import { Effect, Layer } from "effect";
11
5
  import { HttpRouter, HttpServerRequest } from "effect/unstable/http";
12
6
  import { HttpApiMiddleware } from "effect/unstable/httpapi";
13
- import { requestRef } from "../location";
7
+ import { requestRef, sessionRef } from "../location";
14
8
 
15
9
  export class FormLocationMiddleware extends HttpApiMiddleware.Service()("@opencode/HttpApiFormLocation", {
16
10
  error: [InvalidRequestError, SessionNotFoundError]
17
11
  }) {
18
12
  }
19
- const decodeSessionID = Schema.decodeUnknownEffect(Session.ID);
20
13
  export const formLocationLayer = Layer.effect(FormLocationMiddleware, Effect.gen(function* () {
21
- const { db } = yield* Database.Service, locations = yield* LocationServiceMap.Service;
14
+ const database = yield* Database.Service, locations = yield* LocationServiceMap.Service;
22
15
  return FormLocationMiddleware.of((effect) => Effect.gen(function* () {
23
16
  const route = yield* HttpRouter.RouteContext;
24
17
  if (route.params.sessionID === "global") {
25
18
  const request = yield* HttpServerRequest.HttpServerRequest;
26
19
  return yield* effect.pipe(Effect.provide(locations.get(requestRef(request))));
27
20
  }
28
- const sessionID = yield* decodeSessionID(route.params.sessionID).pipe(Effect.mapError(() => new InvalidRequestError({
29
- message: "Invalid session ID",
30
- field: "sessionID"
31
- }))), row = yield* db.select({ directory: SessionTable.directory, workspaceID: SessionTable.workspace_id }).from(SessionTable).where(eq(SessionTable.id, sessionID)).get().pipe(Effect.orDie);
32
- if (!row)
33
- return yield* new SessionNotFoundError({
34
- sessionID,
35
- message: `Session not found: ${sessionID}`
36
- });
37
- return yield* effect.pipe(Effect.provide(locations.get(Location.Ref.make({
38
- directory: AbsolutePath.make(row.directory),
39
- workspaceID: row.workspaceID ? Workspace.ID.make(row.workspaceID) : void 0
40
- }))));
21
+ const ref = yield* sessionRef(database, route.params.sessionID);
22
+ return yield* effect.pipe(Effect.provide(locations.get(ref)));
41
23
  }));
42
24
  }));
@@ -1,17 +1,16 @@
1
1
  import { Database } from "@opencode-ai/core/database/database";
2
2
  import { LocationServiceMap } from "@opencode-ai/core/location-services";
3
- import { Location } from "@opencode-ai/core/location";
4
3
  import { Layer } from "effect";
5
4
  import { HttpApiMiddleware } from "effect/unstable/httpapi";
6
5
  import { InvalidRequestError, SessionNotFoundError } from "@opencode-ai/protocol/errors";
7
6
  declare const SessionLocationMiddleware_base: HttpApiMiddleware.ServiceClass<SessionLocationMiddleware, "@opencode/HttpApiSessionLocation", {
8
7
  requires: never;
9
- provides: Location.Service | import("@opencode-ai/core/config").Service | import("@opencode-ai/core/agent").Service | import("@opencode-ai/core/aisdk").Service | import("@opencode-ai/core/form").Service | import("@opencode-ai/core/integration").Service | import("@opencode-ai/core/catalog").Service | import("@opencode-ai/core/command").Service | import("@opencode-ai/core/environment/environment").Service | import("@opencode-ai/core/mcp/index").Service | import("@opencode-ai/core/file-mutation").Service | import("@opencode-ai/core/formatter").Service | import("@opencode-ai/core/filesystem/search").Service | import("@opencode-ai/core/filesystem").Service | import("@opencode-ai/core/model-resolver").Service | import("@opencode-ai/core/generate").Service | import("@opencode-ai/core/image").Service | import("@opencode-ai/core/plugin/supervisor-service").Service | import("@opencode-ai/core/plugin/instance").Service | import("@opencode-ai/core/plugin/hooks").Service | import("@opencode-ai/core/permission").Service | import("@opencode-ai/core/location-mutation").Service | import("@opencode-ai/core/session/instructions").Service | import("@opencode-ai/core/tool/read-filesystem").Service | import("@opencode-ai/core/shell/select").Service | import("@opencode-ai/core/instruction-discovery").Service | import("@opencode-ai/core/instructions/builtins").Service | import("@opencode-ai/core/tool").Service | import("@opencode-ai/core/tool/mcp").Service | import("@opencode-ai/core/reference").Service | import("@opencode-ai/core/reference/instructions").Service | import("@opencode-ai/core/skill").Service | import("@opencode-ai/core/skill/instructions").Service | import("@opencode-ai/core/session/instruction-entry").Service | import("@opencode-ai/core/session/model-transport").Service | import("@opencode-ai/core/session/runner/model").Service | import("@opencode-ai/core/plugin").Service | import("@opencode-ai/core/shell").Service | import("@opencode-ai/core/websearch").Service | import("@opencode-ai/core/session/compaction").Service | import("@opencode-ai/core/snapshot").Service | import("@opencode-ai/core/tool-output").Service | import("@opencode-ai/core/vcs").Service | import("@opencode-ai/core/filesystem/location-watcher").Service | import("@opencode-ai/core/pty").Service | import("@opencode-ai/core/session/title").Service | import("@opencode-ai/core/session/runner/index").Service | import("@opencode-ai/core/session/generate").Service;
8
+ provides: import("@opencode-ai/core/location").Service | import("@opencode-ai/core/config").Service | import("@opencode-ai/core/agent").Service | import("@opencode-ai/core/aisdk").Service | import("@opencode-ai/core/form").Service | import("@opencode-ai/core/integration").Service | import("@opencode-ai/core/catalog").Service | import("@opencode-ai/core/command").Service | import("@opencode-ai/core/environment/environment").Service | import("@opencode-ai/core/mcp/index").Service | import("@opencode-ai/core/file-mutation").Service | import("@opencode-ai/core/formatter").Service | import("@opencode-ai/core/filesystem/search").Service | import("@opencode-ai/core/filesystem").Service | import("@opencode-ai/core/model-resolver").Service | import("@opencode-ai/core/generate").Service | import("@opencode-ai/core/image").Service | import("@opencode-ai/core/plugin/supervisor-service").Service | import("@opencode-ai/core/plugin/instance").Service | import("@opencode-ai/core/plugin/hooks").Service | import("@opencode-ai/core/permission").Service | import("@opencode-ai/core/location-mutation").Service | import("@opencode-ai/core/session/instructions").Service | import("@opencode-ai/core/tool/read-filesystem").Service | import("@opencode-ai/core/shell/select").Service | import("@opencode-ai/core/instruction-discovery").Service | import("@opencode-ai/core/instructions/builtins").Service | import("@opencode-ai/core/tool").Service | import("@opencode-ai/core/tool/mcp").Service | import("@opencode-ai/core/reference").Service | import("@opencode-ai/core/reference/instructions").Service | import("@opencode-ai/core/skill").Service | import("@opencode-ai/core/skill/instructions").Service | import("@opencode-ai/core/session/instruction-entry").Service | import("@opencode-ai/core/session/model-transport").Service | import("@opencode-ai/core/session/runner/model").Service | import("@opencode-ai/core/plugin").Service | import("@opencode-ai/core/shell").Service | import("@opencode-ai/core/session/prompt").Service | import("@opencode-ai/core/session/revert").Service | import("@opencode-ai/core/websearch").Service | import("@opencode-ai/core/session/compaction").Service | import("@opencode-ai/core/snapshot").Service | import("@opencode-ai/core/tool-output").Service | import("@opencode-ai/core/vcs").Service | import("@opencode-ai/core/session/runner/index").Service | import("@opencode-ai/core/pty").Service | import("@opencode-ai/core/session/generate").Service | import("@opencode-ai/core/session/title").Service | import("@opencode-ai/core/filesystem/location-watcher").Service;
10
9
  error: readonly [typeof InvalidRequestError, typeof SessionNotFoundError];
11
10
  clientError: never;
12
11
  requiredForClient: false;
13
12
  security: never;
14
- }, HttpApiMiddleware.HttpApiMiddleware<Location.Service | import("@opencode-ai/core/config").Service | import("@opencode-ai/core/agent").Service | import("@opencode-ai/core/aisdk").Service | import("@opencode-ai/core/form").Service | import("@opencode-ai/core/integration").Service | import("@opencode-ai/core/catalog").Service | import("@opencode-ai/core/command").Service | import("@opencode-ai/core/environment/environment").Service | import("@opencode-ai/core/mcp/index").Service | import("@opencode-ai/core/file-mutation").Service | import("@opencode-ai/core/formatter").Service | import("@opencode-ai/core/filesystem/search").Service | import("@opencode-ai/core/filesystem").Service | import("@opencode-ai/core/model-resolver").Service | import("@opencode-ai/core/generate").Service | import("@opencode-ai/core/image").Service | import("@opencode-ai/core/plugin/supervisor-service").Service | import("@opencode-ai/core/plugin/instance").Service | import("@opencode-ai/core/plugin/hooks").Service | import("@opencode-ai/core/permission").Service | import("@opencode-ai/core/location-mutation").Service | import("@opencode-ai/core/session/instructions").Service | import("@opencode-ai/core/tool/read-filesystem").Service | import("@opencode-ai/core/shell/select").Service | import("@opencode-ai/core/instruction-discovery").Service | import("@opencode-ai/core/instructions/builtins").Service | import("@opencode-ai/core/tool").Service | import("@opencode-ai/core/tool/mcp").Service | import("@opencode-ai/core/reference").Service | import("@opencode-ai/core/reference/instructions").Service | import("@opencode-ai/core/skill").Service | import("@opencode-ai/core/skill/instructions").Service | import("@opencode-ai/core/session/instruction-entry").Service | import("@opencode-ai/core/session/model-transport").Service | import("@opencode-ai/core/session/runner/model").Service | import("@opencode-ai/core/plugin").Service | import("@opencode-ai/core/shell").Service | import("@opencode-ai/core/websearch").Service | import("@opencode-ai/core/session/compaction").Service | import("@opencode-ai/core/snapshot").Service | import("@opencode-ai/core/tool-output").Service | import("@opencode-ai/core/vcs").Service | import("@opencode-ai/core/filesystem/location-watcher").Service | import("@opencode-ai/core/pty").Service | import("@opencode-ai/core/session/title").Service | import("@opencode-ai/core/session/runner/index").Service | import("@opencode-ai/core/session/generate").Service, readonly [typeof InvalidRequestError, typeof SessionNotFoundError], never>>;
13
+ }, HttpApiMiddleware.HttpApiMiddleware<import("@opencode-ai/core/location").Service | import("@opencode-ai/core/config").Service | import("@opencode-ai/core/agent").Service | import("@opencode-ai/core/aisdk").Service | import("@opencode-ai/core/form").Service | import("@opencode-ai/core/integration").Service | import("@opencode-ai/core/catalog").Service | import("@opencode-ai/core/command").Service | import("@opencode-ai/core/environment/environment").Service | import("@opencode-ai/core/mcp/index").Service | import("@opencode-ai/core/file-mutation").Service | import("@opencode-ai/core/formatter").Service | import("@opencode-ai/core/filesystem/search").Service | import("@opencode-ai/core/filesystem").Service | import("@opencode-ai/core/model-resolver").Service | import("@opencode-ai/core/generate").Service | import("@opencode-ai/core/image").Service | import("@opencode-ai/core/plugin/supervisor-service").Service | import("@opencode-ai/core/plugin/instance").Service | import("@opencode-ai/core/plugin/hooks").Service | import("@opencode-ai/core/permission").Service | import("@opencode-ai/core/location-mutation").Service | import("@opencode-ai/core/session/instructions").Service | import("@opencode-ai/core/tool/read-filesystem").Service | import("@opencode-ai/core/shell/select").Service | import("@opencode-ai/core/instruction-discovery").Service | import("@opencode-ai/core/instructions/builtins").Service | import("@opencode-ai/core/tool").Service | import("@opencode-ai/core/tool/mcp").Service | import("@opencode-ai/core/reference").Service | import("@opencode-ai/core/reference/instructions").Service | import("@opencode-ai/core/skill").Service | import("@opencode-ai/core/skill/instructions").Service | import("@opencode-ai/core/session/instruction-entry").Service | import("@opencode-ai/core/session/model-transport").Service | import("@opencode-ai/core/session/runner/model").Service | import("@opencode-ai/core/plugin").Service | import("@opencode-ai/core/shell").Service | import("@opencode-ai/core/session/prompt").Service | import("@opencode-ai/core/session/revert").Service | import("@opencode-ai/core/websearch").Service | import("@opencode-ai/core/session/compaction").Service | import("@opencode-ai/core/snapshot").Service | import("@opencode-ai/core/tool-output").Service | import("@opencode-ai/core/vcs").Service | import("@opencode-ai/core/session/runner/index").Service | import("@opencode-ai/core/pty").Service | import("@opencode-ai/core/session/generate").Service | import("@opencode-ai/core/session/title").Service | import("@opencode-ai/core/filesystem/location-watcher").Service, readonly [typeof InvalidRequestError, typeof SessionNotFoundError], never>>;
15
14
  export declare class SessionLocationMiddleware extends SessionLocationMiddleware_base {
16
15
  }
17
16
  export declare const sessionLocationLayer: Layer.Layer<SessionLocationMiddleware, never, Database.Service | LocationServiceMap.Service>;
@@ -1,36 +1,19 @@
1
1
  import { Database } from "@opencode-ai/core/database/database";
2
2
  import { LocationServiceMap } from "@opencode-ai/core/location-services";
3
- import { Location } from "@opencode-ai/core/location";
4
- import { AbsolutePath } from "@opencode-ai/core/schema";
5
- import { Session } from "@opencode-ai/core/session";
6
- import { SessionTable } from "@opencode-ai/core/session/sql";
7
- import { Workspace } from "@opencode-ai/core/workspace";
8
- import { eq } from "drizzle-orm";
9
- import { Effect, Layer, Schema } from "effect";
3
+ import { Effect, Layer } from "effect";
10
4
  import { HttpRouter } from "effect/unstable/http";
11
5
  import { HttpApiMiddleware } from "effect/unstable/httpapi";
12
6
  import { InvalidRequestError, SessionNotFoundError } from "@opencode-ai/protocol/errors";
7
+ import { sessionRef } from "../location";
13
8
 
14
9
  export class SessionLocationMiddleware extends HttpApiMiddleware.Service()("@opencode/HttpApiSessionLocation", {
15
10
  error: [InvalidRequestError, SessionNotFoundError]
16
11
  }) {
17
12
  }
18
- const decodeSessionID = Schema.decodeUnknownEffect(Session.ID);
19
13
  export const sessionLocationLayer = Layer.effect(SessionLocationMiddleware, Effect.gen(function* () {
20
- const { db } = yield* Database.Service, locations = yield* LocationServiceMap.Service;
14
+ const database = yield* Database.Service, locations = yield* LocationServiceMap.Service;
21
15
  return SessionLocationMiddleware.of((effect) => Effect.gen(function* () {
22
- const route = yield* HttpRouter.RouteContext, sessionID = yield* decodeSessionID(route.params.sessionID).pipe(Effect.mapError(() => new InvalidRequestError({
23
- message: "Invalid session ID",
24
- field: "sessionID"
25
- }))), row = yield* db.select({ directory: SessionTable.directory, workspaceID: SessionTable.workspace_id }).from(SessionTable).where(eq(SessionTable.id, sessionID)).get().pipe(Effect.orDie);
26
- if (!row)
27
- return yield* new SessionNotFoundError({
28
- sessionID,
29
- message: `Session not found: ${sessionID}`
30
- });
31
- return yield* effect.pipe(Effect.provide(locations.get(Location.Ref.make({
32
- directory: AbsolutePath.make(row.directory),
33
- workspaceID: row.workspaceID ? Workspace.ID.make(row.workspaceID) : void 0
34
- }))));
16
+ const route = yield* HttpRouter.RouteContext, ref = yield* sessionRef(database, route.params.sessionID);
17
+ return yield* effect.pipe(Effect.provide(locations.get(ref)));
35
18
  }));
36
19
  }));
package/dist/options.d.ts CHANGED
@@ -8,6 +8,7 @@ export declare const ServerOptions: Schema.Struct<{
8
8
  readonly hostname: Schema.optional<Schema.String>;
9
9
  readonly port: Schema.optional<Schema.Int>;
10
10
  readonly password: Schema.optional<Schema.String>;
11
+ readonly cors: Schema.optional<Schema.$Array<Schema.String>>;
11
12
  readonly simulation: Schema.optional<Schema.Boolean>;
12
13
  readonly database: Schema.optional<Schema.Struct<{
13
14
  readonly path: Schema.optional<Schema.String>;
package/dist/options.js CHANGED
@@ -11,6 +11,7 @@ export const ServerOptions = Schema.Struct({
11
11
  hostname: Schema.optional(Schema.String),
12
12
  port: Schema.optional(Schema.Int.check(Schema.isGreaterThanOrEqualTo(0), Schema.isLessThanOrEqualTo(65535))),
13
13
  password: Schema.optional(Schema.String),
14
+ cors: Schema.optional(Schema.Array(Schema.String)),
14
15
  simulation: Schema.optional(Schema.Boolean),
15
16
  database: Schema.optional(Database.Options),
16
17
  pty: Schema.optional(PersistentPty.Options),
package/dist/process.d.ts CHANGED
@@ -35,6 +35,7 @@ export declare const start: <E, R>(options: {
35
35
  readonly gitbash?: string | undefined;
36
36
  } | undefined;
37
37
  readonly port?: number | undefined;
38
+ readonly cors?: readonly string[] | undefined;
38
39
  readonly password?: string | undefined;
39
40
  readonly app?: {
40
41
  readonly version?: string | undefined;
package/dist/process.js CHANGED
@@ -26,7 +26,7 @@ export const start = Effect.fn("ServerProcess.start")(function* (options, lifecy
26
26
  if (!password)
27
27
  return yield* Effect.fail(Error("Missing server password"));
28
28
  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 }), application = yield* Ref.make(Option.none());
29
- yield* bound.http.serve(dispatch(password, status, application, options.app?.version ?? "unknown").pipe(HttpMiddleware.cors({ allowedOrigins: isAllowedCorsOrigin, maxAge: 86400 })), errorResponseLogger).pipe(withoutParentSpan);
29
+ yield* bound.http.serve(dispatch(password, status, application, options.app?.version ?? "unknown").pipe(HttpMiddleware.cors({ allowedOrigins: (origin) => isAllowedCorsOrigin(origin, options), maxAge: 86400 })), errorResponseLogger).pipe(withoutParentSpan);
30
30
  if (lifecycle)
31
31
  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);
32
32
  const parentScope = yield* Scope.Scope, applicationScope = yield* Scope.fork(parentScope);
package/dist/routes.d.ts CHANGED
@@ -21,5 +21,5 @@ import { HttpRouter } from "effect/unstable/http";
21
21
  import { Layer } from "effect";
22
22
  import { PtyEnvironment } from "./pty-environment";
23
23
  import type { ServerOptions } from "./options";
24
- 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 | Credential.Service | WellKnown.Service | Workspace.Service | Job.Service | PermissionSaved.Service | SdkPlugins.Service | Worktree.Service | Project.Service | LocationServiceMap.Service | PersistentPty.Service | Session.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>;
25
- export declare function createEmbeddedRoutes(options?: ServerOptions, overrides?: LayerNode.Replacements): Layer.Layer<Global.Service | Database.Service | Bus.Service | import("effect/unstable/http/HttpClient").HttpClient | Credential.Service | WellKnown.Service | Workspace.Service | Job.Service | PermissionSaved.Service | SdkPlugins.Service | Worktree.Service | Project.Service | LocationServiceMap.Service | PersistentPty.Service | Session.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>;
24
+ 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 | Credential.Service | WellKnown.Service | Workspace.Service | Job.Service | PermissionSaved.Service | SdkPlugins.Service | LocationServiceMap.Service | Worktree.Service | Session.Service | Project.Service | PersistentPty.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>;
25
+ export declare function createEmbeddedRoutes(options?: ServerOptions, overrides?: LayerNode.Replacements): Layer.Layer<Global.Service | Database.Service | Bus.Service | import("effect/unstable/http/HttpClient").HttpClient | Credential.Service | WellKnown.Service | Workspace.Service | Job.Service | PermissionSaved.Service | SdkPlugins.Service | LocationServiceMap.Service | Worktree.Service | Session.Service | Project.Service | PersistentPty.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>;
package/dist/routes.js CHANGED
@@ -35,6 +35,7 @@ import { HttpApiBuilder } from "effect/unstable/httpapi";
35
35
  import { Context, Effect, Layer, Option } from "effect";
36
36
  import { Api } from "./api";
37
37
  import { ServerAuth } from "./auth";
38
+ import { CorsConfig } from "./cors";
38
39
  import { handlers } from "./handlers";
39
40
  import { authorizationLayer } from "./middleware/authorization";
40
41
  import { schemaErrorLayer } from "./middleware/schema-error";
@@ -109,7 +110,7 @@ function makeRoutes(auth, options, serviceURLs, overrides) {
109
110
  const { simulationReplacements } = yield* Effect.promise(() => import("@opencode-ai/simulation/backend")), simulation = yield* simulationReplacements({ version: App.make(options.app).version });
110
111
  return AppNodeBuilder.build(applicationServices, [...replacements, ...simulation]);
111
112
  })) : AppNodeBuilder.build(applicationServices, replacements)).pipe(Layer.flatMap((context) => {
112
- const services = Layer.succeedContext(context), requestServices = Layer.merge(Layer.succeedContext(Context.pick(Database.Service, PermissionSaved.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(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));
113
+ const services = Layer.succeedContext(context), requestServices = Layer.merge(Layer.succeedContext(Context.pick(Database.Service, PermissionSaved.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));
113
114
  return Layer.merge(api, V1Migration.layer.pipe(Layer.provide(services)));
114
115
  }));
115
116
  }
package/dist/workerd.js CHANGED
@@ -37,6 +37,7 @@ export function replacements(options) {
37
37
  ];
38
38
  }
39
39
  const unavailable = (what) => Effect.die(Error(`${what} is unavailable in the workerd profile`)), vcsLayer = Layer.succeed(Vcs.Service, Vcs.Service.of({
40
+ base: () => Effect.succeed(null),
40
41
  transform: () => Effect.succeed({ dispose: Effect.void }),
41
42
  reload: () => Effect.void,
42
43
  info: () => Effect.succeed({ branch: {} }),
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/package.json",
3
3
  "name": "@opencode-ai/server",
4
- "version": "0.0.0-beta-18593",
4
+ "version": "0.0.0-beta-18684",
5
5
  "type": "module",
6
6
  "license": "MIT",
7
7
  "repository": {
@@ -30,11 +30,11 @@
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-ai/core": "0.0.0-beta-18593",
34
- "@opencode-ai/protocol": "0.0.0-beta-18593",
35
- "@opencode-ai/schema": "0.0.0-beta-18593",
36
- "@opencode-ai/simulation": "0.0.0-beta-18593",
37
- "@opencode-ai/util": "0.0.0-beta-18593",
33
+ "@opencode-ai/core": "0.0.0-beta-18684",
34
+ "@opencode-ai/protocol": "0.0.0-beta-18684",
35
+ "@opencode-ai/schema": "0.0.0-beta-18684",
36
+ "@opencode-ai/simulation": "0.0.0-beta-18684",
37
+ "@opencode-ai/util": "0.0.0-beta-18684",
38
38
  "drizzle-orm": "1.0.0-rc.5-169397b",
39
39
  "effect": "4.0.0-rc.112"
40
40
  },