@opencode/server 2.1.3 → 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (132) hide show
  1. package/dist/api.d.ts +854 -969
  2. package/dist/api.js +5 -5
  3. package/dist/auth.js +1 -1
  4. package/dist/chunks/server-info-1gwc8nvb.js +69 -0
  5. package/dist/chunks/{service-status-z554rpg5.js → server-info-1v577ncx.js} +4 -2
  6. package/dist/chunks/{service-status-79n3507d.js → server-info-1wd9c1m3.js} +3 -3
  7. package/dist/chunks/{service-status-jwf0kwqx.js → server-info-2eaky32g.js} +12 -3
  8. package/dist/chunks/{service-status-a30hykaf.js → server-info-2h6qktqa.js} +24 -6
  9. package/dist/chunks/{service-status-6tj91hdj.js → server-info-4fy84009.js} +3 -3
  10. package/dist/chunks/{service-status-yzwm8eeq.js → server-info-4q6e7fh8.js} +2 -2
  11. package/dist/chunks/{service-status-gymtz25n.js → server-info-50bbk3b2.js} +3 -3
  12. package/dist/chunks/{service-status-rj8tbp10.js → server-info-5b42hxrf.js} +1 -1
  13. package/dist/chunks/{service-status-x2cwbfak.js → server-info-5pdfedjd.js} +7 -7
  14. package/dist/chunks/{service-status-1qc831kp.js → server-info-5s6gh8sx.js} +7 -3
  15. package/dist/chunks/{service-status-vg0x3zn0.js → server-info-6z9pvq7p.js} +1 -1
  16. package/dist/chunks/{service-status-6v4wsps6.js → server-info-7b9xm1qg.js} +3 -2
  17. package/dist/chunks/{service-status-7qrtcnv4.js → server-info-a8jcac9a.js} +1 -1
  18. package/dist/chunks/{service-status-5ewqf72w.js → server-info-az0609r6.js} +4 -2
  19. package/dist/chunks/server-info-b0f38s3n.js +105 -0
  20. package/dist/chunks/server-info-b105zy65.js +22 -0
  21. package/dist/chunks/{service-status-x74w7e1f.js → server-info-b3bmdkga.js} +1 -1
  22. package/dist/chunks/{service-status-erzfdgke.js → server-info-bd8755ek.js} +16 -1
  23. package/dist/chunks/server-info-bhbc7551.js +107 -0
  24. package/dist/chunks/{service-status-11d378s5.js → server-info-btahnm2b.js} +3 -3
  25. package/dist/chunks/{service-status-c2hv5jmf.js → server-info-cezwbsk5.js} +1 -1
  26. package/dist/chunks/{service-status-crt28xe4.js → server-info-d0edqfxx.js} +4 -11
  27. package/dist/chunks/{service-status-e6e4kz0w.js → server-info-e6e4kz0w.js} +1 -1
  28. package/dist/chunks/{service-status-5adf1am9.js → server-info-f559fakr.js} +2 -2
  29. package/dist/chunks/{service-status-pf9k0dqe.js → server-info-h29xjj1e.js} +2 -2
  30. package/dist/chunks/{service-status-3154e7fk.js → server-info-htyf2qs7.js} +5 -3
  31. package/dist/chunks/{service-status-5680j7c4.js → server-info-j2d131x1.js} +23 -20
  32. package/dist/chunks/{service-status-j4at0y5c.js → server-info-j4at0y5c.js} +1 -1
  33. package/dist/chunks/{service-status-r82dtfrk.js → server-info-j87xz9bt.js} +3 -3
  34. package/dist/chunks/{service-status-y89d99mz.js → server-info-kkdkqt8j.js} +2 -2
  35. package/dist/chunks/{service-status-vb61dkrm.js → server-info-kqr36gas.js} +8 -8
  36. package/dist/chunks/server-info-n321d8vm.js +46 -0
  37. package/dist/chunks/{service-status-rkmbbexc.js → server-info-nx6f5k7a.js} +4 -4
  38. package/dist/chunks/{service-status-0znmasm1.js → server-info-ny1j968n.js} +2 -2
  39. package/dist/chunks/server-info-qcg3sqtb.js +38 -0
  40. package/dist/chunks/{service-status-6e6jjne7.js → server-info-qd0r787n.js} +2 -2
  41. package/dist/chunks/{service-status-xcxwzp6z.js → server-info-rha2aq18.js} +4 -4
  42. package/dist/chunks/{service-status-6tjqh8g4.js → server-info-rw1dfckh.js} +8 -4
  43. package/dist/chunks/{service-status-2e16a9cc.js → server-info-s282vggx.js} +1 -1
  44. package/dist/chunks/{service-status-k6dz4enc.js → server-info-s802fzg1.js} +21 -20
  45. package/dist/chunks/{service-status-10kexchg.js → server-info-te8jwba1.js} +2 -2
  46. package/dist/chunks/{service-status-53jj3zgg.js → server-info-tjtyxt9h.js} +32 -12
  47. package/dist/chunks/server-info-xthc02cw.js +6 -0
  48. package/dist/chunks/server-info-yqhefp4s.js +83 -0
  49. package/dist/chunks/{service-status-7scj3y0h.js → server-info-yxw63vq5.js} +10 -8
  50. package/dist/chunks/{service-status-krqg3gd2.js → server-info-zcvan105.js} +1 -1
  51. package/dist/chunks/{service-status-q6jxy1hn.js → server-info-zpr61asr.js} +15 -38
  52. package/dist/cors.js +1 -1
  53. package/dist/event-feed.d.ts +1 -1
  54. package/dist/event-feed.js +3 -3
  55. package/dist/fetch.js +50 -48
  56. package/dist/handlers/agent.js +6 -6
  57. package/dist/handlers/command.js +6 -6
  58. package/dist/handlers/config.js +6 -6
  59. package/dist/handlers/credential.js +6 -6
  60. package/dist/handlers/debug.d.ts +2 -1
  61. package/dist/handlers/debug.js +6 -6
  62. package/dist/handlers/event.js +7 -7
  63. package/dist/handlers/form.js +6 -6
  64. package/dist/handlers/fs.d.ts +2 -1
  65. package/dist/handlers/fs.js +6 -6
  66. package/dist/handlers/generate.d.ts +1 -1
  67. package/dist/handlers/generate.js +6 -6
  68. package/dist/handlers/integration.js +6 -6
  69. package/dist/handlers/location.js +6 -6
  70. package/dist/handlers/mcp.d.ts +3 -1
  71. package/dist/handlers/mcp.js +8 -6
  72. package/dist/handlers/media.d.ts +6 -0
  73. package/dist/handlers/media.js +6 -0
  74. package/dist/handlers/message.js +7 -6
  75. package/dist/handlers/migration.js +6 -6
  76. package/dist/handlers/model.js +6 -6
  77. package/dist/handlers/permission.js +6 -6
  78. package/dist/handlers/persistent-pty.d.ts +1 -1
  79. package/dist/handlers/persistent-pty.js +9 -8
  80. package/dist/handlers/plugin.js +6 -6
  81. package/dist/handlers/project.d.ts +1 -1
  82. package/dist/handlers/project.js +6 -6
  83. package/dist/handlers/provider.js +6 -6
  84. package/dist/handlers/pty-socket.js +1 -1
  85. package/dist/handlers/pty.d.ts +1 -2
  86. package/dist/handlers/pty.js +8 -9
  87. package/dist/handlers/reference.js +6 -6
  88. package/dist/handlers/rpc.js +6 -6
  89. package/dist/handlers/server.js +9 -9
  90. package/dist/handlers/session-error.js +1 -1
  91. package/dist/handlers/session.d.ts +3 -1
  92. package/dist/handlers/session.js +7 -6
  93. package/dist/handlers/shell.js +6 -6
  94. package/dist/handlers/skill.js +6 -6
  95. package/dist/handlers/usage.d.ts +1 -0
  96. package/dist/handlers/usage.js +11 -0
  97. package/dist/handlers/vcs.js +6 -6
  98. package/dist/handlers/voice.d.ts +1 -1
  99. package/dist/handlers/voice.js +6 -6
  100. package/dist/handlers/websearch.js +6 -6
  101. package/dist/handlers/worktree.js +6 -6
  102. package/dist/handlers.d.ts +1 -1
  103. package/dist/handlers.js +46 -44
  104. package/dist/location.js +4 -4
  105. package/dist/media-uri.d.ts +6 -0
  106. package/dist/media-uri.js +6 -0
  107. package/dist/middleware/authorization.js +2 -2
  108. package/dist/middleware/form-location.js +3 -3
  109. package/dist/middleware/schema-error.js +1 -1
  110. package/dist/middleware/session-location.js +3 -3
  111. package/dist/pairing.js +5 -5
  112. package/dist/process.js +54 -51
  113. package/dist/request-tracing.js +1 -1
  114. package/dist/routes.d.ts +5 -3
  115. package/dist/routes.js +49 -47
  116. package/dist/server-info.js +5 -5
  117. package/dist/service-status.js +1 -1
  118. package/dist/workerd.js +51 -49
  119. package/package.json +12 -10
  120. package/dist/chunks/service-status-0f489yfb.js +0 -102
  121. package/dist/chunks/service-status-2f9g7rg2.js +0 -20
  122. package/dist/chunks/service-status-hwdnjend.js +0 -40
  123. package/dist/chunks/service-status-j3461ttv.js +0 -59
  124. package/dist/chunks/service-status-z9g9xjb3.js +0 -30
  125. package/dist/chunks/service-status-zy1wt1f8.js +0 -23
  126. package/dist/pty-environment.d.ts +0 -13
  127. package/dist/pty-environment.js +0 -12
  128. /package/dist/chunks/{service-status-9rqn6x4v.js → server-info-9rqn6x4v.js} +0 -0
  129. /package/dist/chunks/{service-status-h6rt5k9s.js → server-info-h6rt5k9s.js} +0 -0
  130. /package/dist/chunks/{service-status-q4bn6dy8.js → server-info-q4bn6dy8.js} +0 -0
  131. /package/dist/chunks/{service-status-smaf4a18.js → server-info-smaf4a18.js} +0 -0
  132. /package/dist/chunks/{service-status-yc7nft6q.js → server-info-yc7nft6q.js} +0 -0
@@ -0,0 +1,107 @@
1
+ import {
2
+ locationErrors2,
3
+ response2,
4
+ requestRef2
5
+ } from "./server-info-50bbk3b2.js";
6
+ import {
7
+ Api2
8
+ } from "./server-info-j87xz9bt.js";
9
+ import {
10
+ CorsConfig2,
11
+ isAllowedRequestOrigin2
12
+ } from "./server-info-q4bn6dy8.js";
13
+ import {
14
+ runPtySocket2
15
+ } from "./server-info-h6rt5k9s.js";
16
+
17
+ // src/handlers/mcp.ts
18
+ import { Location } from "@opencode/core/location";
19
+ import { LocationServiceMap } from "@opencode/core/location-service-map";
20
+ import { Mcp } from "@opencode/core/mcp/index";
21
+ import { PtyTicket } from "@opencode/core/pty/ticket";
22
+ import { ForbiddenError, McpServerNotFoundError } from "@opencode/protocol/errors";
23
+ import { PTY_CONNECT_TOKEN_HEADER, PTY_CONNECT_TOKEN_HEADER_VALUE } from "@opencode/protocol/groups/pty";
24
+ import { Effect, Queue } from "effect";
25
+ import { HttpServerResponse } from "effect/http";
26
+ import { HttpApiBuilder, HttpApiSchema } from "effect/http-api";
27
+ import { Socket } from "effect/socket";
28
+ var notFound = (effect) => effect.pipe(Effect.mapError((error) => new McpServerNotFoundError({ server: error.server, message: error.message })));
29
+ var McpHandler2 = HttpApiBuilder.group(Api2, "server.mcp", (handlers) => Effect.gen(function* () {
30
+ const locations = yield* LocationServiceMap.Service;
31
+ const cors = yield* CorsConfig2;
32
+ const tickets = yield* PtyTicket.Service;
33
+ return handlers.handle("mcp.list", Effect.fn(function* () {
34
+ const service = yield* Mcp.Service;
35
+ return yield* response2(service.servers());
36
+ })).handle("mcp.add", Effect.fn(function* (ctx) {
37
+ const service = yield* Mcp.Service;
38
+ yield* service.add(ctx.params.server, ctx.payload.config);
39
+ return HttpApiSchema.NoContent.make();
40
+ })).handle("mcp.remove", Effect.fn(function* (ctx) {
41
+ const service = yield* Mcp.Service;
42
+ yield* notFound(service.remove(ctx.params.server));
43
+ return HttpApiSchema.NoContent.make();
44
+ })).handle("mcp.connect", Effect.fn(function* (ctx) {
45
+ const service = yield* Mcp.Service;
46
+ yield* notFound(service.connect(ctx.params.server));
47
+ return HttpApiSchema.NoContent.make();
48
+ })).handle("mcp.disconnect", Effect.fn(function* (ctx) {
49
+ const service = yield* Mcp.Service;
50
+ yield* notFound(service.disconnect(ctx.params.server));
51
+ return HttpApiSchema.NoContent.make();
52
+ })).handle("mcp.resource.catalog", Effect.fn(function* () {
53
+ const service = yield* Mcp.Service;
54
+ return yield* response2(service.resourceCatalog());
55
+ })).handle("mcp.clientToken", Effect.fn(function* (ctx) {
56
+ if (ctx.headers[PTY_CONNECT_TOKEN_HEADER] !== PTY_CONNECT_TOKEN_HEADER_VALUE || !isAllowedRequestOrigin2(ctx.request.headers.origin, ctx.request.headers.host, cors))
57
+ return yield* new ForbiddenError({ message: "Invalid client MCP connect token request" });
58
+ const location = yield* Location.Service;
59
+ return yield* response2(tickets.issue({
60
+ mcpClient: ctx.query.name,
61
+ directory: location.directory,
62
+ workspaceID: location.workspaceID
63
+ }));
64
+ })).handleRaw("mcp.client", Effect.fn("McpHandler.client")(function* (ctx) {
65
+ if (!isAllowedRequestOrigin2(ctx.request.headers.origin, ctx.request.headers.host, cors))
66
+ return HttpServerResponse.empty({ status: 403 });
67
+ const name = ctx.query.name;
68
+ const ref = LocationServiceMap.canonical(requestRef2(ctx.request));
69
+ if (ctx.query.ticket && !(yield* tickets.consume({
70
+ ticket: ctx.query.ticket,
71
+ mcpClient: name,
72
+ directory: ref.directory,
73
+ workspaceID: ref.workspaceID
74
+ })))
75
+ return HttpServerResponse.empty({ status: 403 });
76
+ return yield* Effect.gen(function* () {
77
+ const mcp = yield* Mcp.Service;
78
+ const { McpSocketClient } = yield* Effect.promise(() => import("@opencode/core/mcp/socket-client"));
79
+ const socket = yield* Effect.orDie(ctx.request.upgrade);
80
+ const outbox = yield* Queue.unbounded();
81
+ const state = { attached: false, disconnected: false };
82
+ const transport = McpSocketClient.make({
83
+ send: (text) => Queue.offerUnsafe(outbox, text),
84
+ close: (code, reason) => {
85
+ if (state.attached)
86
+ Queue.offerUnsafe(outbox, new Socket.CloseEvent(code, reason));
87
+ }
88
+ });
89
+ const decoder = new TextDecoder;
90
+ yield* mcp.attach(name, transport).pipe(Effect.tap(() => Effect.sync(() => {
91
+ state.attached = true;
92
+ })), Effect.catch((error) => state.disconnected ? Effect.logInfo("client MCP disconnected during initialize", { name, error: error.message }) : Effect.logError("client MCP attach failed", { name, error: error.message }).pipe(Effect.andThen(Effect.sync(() => Queue.offerUnsafe(outbox, new Socket.CloseEvent(1011, "attach failed")))))), Effect.forkScoped);
93
+ yield* runPtySocket2({
94
+ socket,
95
+ outbox,
96
+ onMessage: (message) => Effect.sync(() => transport.deliver(typeof message === "string" ? message : decoder.decode(message))),
97
+ detach: () => {
98
+ state.disconnected = true;
99
+ transport.ended();
100
+ }
101
+ });
102
+ return HttpServerResponse.empty();
103
+ }).pipe(Effect.scoped, Effect.provide(locations.get(ref)), locationErrors2);
104
+ }));
105
+ }));
106
+
107
+ export { McpHandler2 };
@@ -1,14 +1,14 @@
1
1
  import {
2
2
  missingSession2
3
- } from "./service-status-smaf4a18.js";
3
+ } from "./server-info-smaf4a18.js";
4
4
  import {
5
5
  locationErrors2,
6
6
  response2,
7
7
  sessionInfo2
8
- } from "./service-status-gymtz25n.js";
8
+ } from "./server-info-50bbk3b2.js";
9
9
  import {
10
10
  Api2
11
- } from "./service-status-r82dtfrk.js";
11
+ } from "./server-info-j87xz9bt.js";
12
12
 
13
13
  // src/handlers/permission.ts
14
14
  import { Instance } from "@opencode/core/instance/service";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  Api2
3
- } from "./service-status-r82dtfrk.js";
3
+ } from "./server-info-j87xz9bt.js";
4
4
 
5
5
  // src/handlers/config.ts
6
6
  import { Config } from "@opencode/core/config";
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  locationErrors2,
3
3
  awaitPlugins2
4
- } from "./service-status-gymtz25n.js";
4
+ } from "./server-info-50bbk3b2.js";
5
5
  import {
6
6
  Api2
7
- } from "./service-status-r82dtfrk.js";
7
+ } from "./server-info-j87xz9bt.js";
8
8
 
9
9
  // src/handlers/voice.ts
10
10
  import { Location } from "@opencode/core/location";
@@ -15,7 +15,6 @@ import { InvalidRequestError, ServiceUnavailableError } from "@opencode/protocol
15
15
  import { Global } from "@opencode/util/global";
16
16
  import { Effect } from "effect";
17
17
  import { HttpApiBuilder } from "effect/http-api";
18
- var voiceErrors = (error) => error._tag === "Voice.InvalidRequestError" ? new InvalidRequestError({ message: error.message }) : new ServiceUnavailableError({ message: error.message, service: error.service });
19
18
  var VoiceHandler2 = HttpApiBuilder.group(Api2, "server.voice", (handlers) => Effect.gen(function* () {
20
19
  const global = yield* Global.Service;
21
20
  const locations = yield* LocationServiceMap.Service;
@@ -27,14 +26,8 @@ var VoiceHandler2 = HttpApiBuilder.group(Api2, "server.voice", (handlers) => Eff
27
26
  }, Effect.provide(services), locationErrors2)).handle("voice.session", Effect.fn("server.voice.session")(function* (request) {
28
27
  yield* awaitPlugins2;
29
28
  const voice = yield* Voice.Service;
30
- const session = yield* voice.session(request.payload).pipe(Effect.mapError(voiceErrors));
31
- return {
32
- data: { transport: session.transport, ...session.id === undefined ? {} : { session: { id: session.id } } }
33
- };
34
- }, Effect.provide(services), locationErrors2)).handle("voice.instructions", Effect.fn("server.voice.instructions")(function* (request) {
35
- yield* awaitPlugins2;
36
- const voice = yield* Voice.Service;
37
- yield* voice.instruct({ id: request.params.sessionID, instructions: request.payload.instructions }).pipe(Effect.mapError(voiceErrors));
29
+ const transport = yield* voice.session(request.payload).pipe(Effect.mapError((error) => error._tag === "Voice.InvalidRequestError" ? new InvalidRequestError({ message: error.message }) : new ServiceUnavailableError({ message: error.message, service: error.service })));
30
+ return { data: { transport } };
38
31
  }, Effect.provide(services), locationErrors2));
39
32
  }));
40
33
 
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  __export
3
- } from "./service-status-9rqn6x4v.js";
3
+ } from "./server-info-9rqn6x4v.js";
4
4
 
5
5
  // src/service-status.ts
6
6
  var exports_service_status = {};
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  response2
3
- } from "./service-status-gymtz25n.js";
3
+ } from "./server-info-50bbk3b2.js";
4
4
  import {
5
5
  Api2
6
- } from "./service-status-r82dtfrk.js";
6
+ } from "./server-info-j87xz9bt.js";
7
7
 
8
8
  // src/handlers/form.ts
9
9
  import { Form } from "@opencode/core/form";
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  response2
3
- } from "./service-status-gymtz25n.js";
3
+ } from "./server-info-50bbk3b2.js";
4
4
  import {
5
5
  Api2
6
- } from "./service-status-r82dtfrk.js";
6
+ } from "./server-info-j87xz9bt.js";
7
7
 
8
8
  // src/handlers/integration.ts
9
9
  import { Integration } from "@opencode/core/integration";
@@ -2,7 +2,7 @@ import {
2
2
  locationErrors2,
3
3
  sessionInfo2,
4
4
  requestRef2
5
- } from "./service-status-gymtz25n.js";
5
+ } from "./server-info-50bbk3b2.js";
6
6
 
7
7
  // src/middleware/form-location.ts
8
8
  import { Instance } from "@opencode/core/instance/service";
@@ -10,7 +10,7 @@ import { LocationServiceMap } from "@opencode/core/location-services";
10
10
  import { Session } from "@opencode/core/session";
11
11
  import { LocationNotFoundError, InvalidRequestError, SessionNotFoundError } from "@opencode/protocol/errors";
12
12
  import { Effect, Layer } from "effect";
13
- import { HttpRouter, HttpServerRequest } from "effect/http";
13
+ import { HttpRouter, HttpServerRequest, HttpServerResponse } from "effect/http";
14
14
  import { HttpApiMiddleware } from "effect/http-api";
15
15
  class FormLocationMiddleware2 extends HttpApiMiddleware.Service()("@opencode/HttpApiFormLocation", {
16
16
  error: [InvalidRequestError, SessionNotFoundError, LocationNotFoundError]
@@ -20,13 +20,15 @@ var formLocationLayer2 = Layer.effect(FormLocationMiddleware2, Effect.gen(functi
20
20
  const sessions = yield* Session.Service;
21
21
  const instances = yield* Instance.Service;
22
22
  const locations = yield* LocationServiceMap.Service;
23
- return FormLocationMiddleware2.of((effect) => Effect.gen(function* () {
23
+ return FormLocationMiddleware2.of((effect, options) => Effect.gen(function* () {
24
24
  const route = yield* HttpRouter.RouteContext;
25
25
  if (route.params.sessionID === "global") {
26
26
  const request = yield* HttpServerRequest.HttpServerRequest;
27
27
  return yield* effect.pipe(Effect.provide(locations.get(requestRef2(request))), locationErrors2);
28
28
  }
29
29
  const session = yield* sessionInfo2(sessions, route.params.sessionID);
30
+ if (options.endpoint.identifier === "session.form.list" && instances.live && !(yield* instances.live(session)))
31
+ return HttpServerResponse.jsonUnsafe({ data: [] });
30
32
  return yield* effect.pipe(instances.provide(session), locationErrors2);
31
33
  }));
32
34
  }));
@@ -1,39 +1,36 @@
1
1
  import {
2
- layer2
3
- } from "./service-status-gymtz25n.js";
2
+ layer4
3
+ } from "./server-info-50bbk3b2.js";
4
4
  import {
5
5
  formLocationLayer2
6
- } from "./service-status-3154e7fk.js";
6
+ } from "./server-info-htyf2qs7.js";
7
7
  import {
8
8
  sessionLocationLayer2
9
- } from "./service-status-x74w7e1f.js";
9
+ } from "./server-info-b3bmdkga.js";
10
10
  import {
11
11
  Api2
12
- } from "./service-status-r82dtfrk.js";
12
+ } from "./server-info-j87xz9bt.js";
13
13
  import {
14
14
  Config2
15
- } from "./service-status-j4at0y5c.js";
15
+ } from "./server-info-j4at0y5c.js";
16
16
  import {
17
17
  CorsConfig2
18
- } from "./service-status-q4bn6dy8.js";
19
- import {
20
- layer5
21
- } from "./service-status-x2cwbfak.js";
18
+ } from "./server-info-q4bn6dy8.js";
22
19
  import {
23
- node3
24
- } from "./service-status-vb61dkrm.js";
20
+ layer2
21
+ } from "./server-info-5pdfedjd.js";
25
22
  import {
26
23
  node2
27
- } from "./service-status-zy1wt1f8.js";
24
+ } from "./server-info-kqr36gas.js";
28
25
  import {
29
26
  handlers2
30
- } from "./service-status-0f489yfb.js";
27
+ } from "./server-info-b0f38s3n.js";
31
28
  import {
32
29
  authorizationLayer2
33
- } from "./service-status-6v4wsps6.js";
30
+ } from "./server-info-7b9xm1qg.js";
34
31
  import {
35
32
  schemaErrorLayer2
36
- } from "./service-status-erzfdgke.js";
33
+ } from "./server-info-bd8755ek.js";
37
34
 
38
35
  // src/routes.ts
39
36
  import { Database } from "@opencode/core/database/database";
@@ -55,10 +52,12 @@ import { Worktree } from "@opencode/core/worktree";
55
52
  import { Session } from "@opencode/core/session";
56
53
  import { Instance } from "@opencode/core/instance/service";
57
54
  import { SessionTransfer } from "@opencode/core/session/transfer";
55
+ import { InstructionEntry } from "@opencode/core/session/instruction-entry";
58
56
  import { ShellSelect } from "@opencode/core/shell/select";
59
57
  import { Job } from "@opencode/core/job";
60
58
  import { Mcp } from "@opencode/core/mcp/index";
61
59
  import { Global } from "@opencode/util/global";
60
+ import { FSUtil } from "@opencode/util/fs-util";
62
61
  import { InstructionDiscovery } from "@opencode/core/instruction-discovery";
63
62
  import { LocationServiceMap } from "@opencode/core/location-service-map";
64
63
  import { LocationActivity } from "@opencode/core/location-activity";
@@ -69,11 +68,13 @@ import { SdkPlugins } from "@opencode/core/plugin/sdk";
69
68
  import { WellKnown } from "@opencode/core/wellknown";
70
69
  import { Workspace } from "@opencode/core/workspace";
71
70
  import { Watcher } from "@opencode/core/filesystem/watcher";
71
+ import { FileWatch } from "@opencode/core/filesystem/file-watch";
72
72
  import { HttpRouter } from "effect/http";
73
73
  import { HttpApiBuilder } from "effect/http-api";
74
74
  import { Context, Effect, Layer, Option } from "effect";
75
75
  var applicationServiceNodes = [
76
76
  Global.node,
77
+ FSUtil.node,
77
78
  Database.node,
78
79
  Bus.node,
79
80
  EventLogger.node,
@@ -85,6 +86,7 @@ var applicationServiceNodes = [
85
86
  Session.node,
86
87
  Instance.node,
87
88
  SessionTransfer.node,
89
+ InstructionEntry.node,
88
90
  SdkPlugins.node,
89
91
  PluginUpdate.node,
90
92
  PermissionSaved.node,
@@ -93,11 +95,11 @@ var applicationServiceNodes = [
93
95
  Credential.node,
94
96
  WellKnown.node,
95
97
  node2,
96
- node3,
97
98
  LocationServiceMap.node,
98
99
  LocationActivity.node,
99
100
  SessionRestart.node,
100
- Workspace.node
101
+ Workspace.node,
102
+ FileWatch.node
101
103
  ];
102
104
  var applicationServices = LayerNode.group(applicationServiceNodes);
103
105
  function createRoutes2(options = {}, serviceURLs = () => [], overrides = []) {
@@ -114,6 +116,7 @@ function makeRoutes(auth, options, serviceURLs, overrides, instances) {
114
116
  App.node.replace(App.configured(options.app)),
115
117
  ModelsDev.node.replace(ModelsDev.configured(options.models)),
116
118
  Watcher.node.replace(Watcher.configured({ enabled: options.fs?.filewatcher })),
119
+ FileWatch.node.replace(FileWatch.configured({ enabled: options.fs?.filewatcher })),
117
120
  FileSystemSearch.node.replace(FileSystemSearch.configured({ fff: options.fs?.fff })),
118
121
  Global.node.replace(Global.layerWith(options.config?.directory ? { config: options.config.directory } : {})),
119
122
  Config.node.replace(Config.configured({
@@ -146,8 +149,8 @@ function makeRoutes(auth, options, serviceURLs, overrides, instances) {
146
149
  })) : build(overrides);
147
150
  return serviceLayer.pipe(Layer.flatMap((context) => {
148
151
  const services = Layer.succeedContext(context);
149
- const requestServices = Layer.merge(Layer.succeedContext(Context.pick(Database.Service, Credential.Service, PermissionSaved.Service, PluginUpdate.Service, Project.Service, WellKnown.Service)(context)), layer5(serviceURLs, Context.get(context, Global.Service).tmp, options.app));
150
- const api = HttpApiBuilder.layer(Api2, { openapiPath: "/openapi.json" }).pipe(Layer.provide(handlers2.pipe(Layer.provide(services), Layer.provide(Layer.succeed(CorsConfig2, options)))), Layer.provide(formLocationLayer2), Layer.provide(sessionLocationLayer2), Layer.provide(layer2), Layer.provide(authorizationLayer2), Layer.provide(schemaErrorLayer2), Layer.provide(auth), HttpRouter.provideRequest(requestServices), Layer.provideMerge(services), Layer.provideMerge(HttpRouter.layer));
152
+ const requestServices = Layer.merge(Layer.succeedContext(Context.pick(Database.Service, Credential.Service, PermissionSaved.Service, PluginUpdate.Service, Project.Service, WellKnown.Service)(context)), layer2(serviceURLs, Context.get(context, Global.Service).tmp, options.app));
153
+ const api = HttpApiBuilder.layer(Api2, { openapiPath: "/openapi.json" }).pipe(Layer.provide(handlers2.pipe(Layer.provide(services), Layer.provide(Layer.succeed(CorsConfig2, options)))), Layer.provide(formLocationLayer2), Layer.provide(sessionLocationLayer2), Layer.provide(layer4), Layer.provide(authorizationLayer2), Layer.provide(schemaErrorLayer2), Layer.provide(auth), HttpRouter.provideRequest(requestServices), Layer.provideMerge(services), Layer.provideMerge(HttpRouter.layer));
151
154
  return Layer.merge(api, V1Migration.layer.pipe(Layer.provide(services)));
152
155
  }));
153
156
  }
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  __export
3
- } from "./service-status-9rqn6x4v.js";
3
+ } from "./server-info-9rqn6x4v.js";
4
4
 
5
5
  // src/auth.ts
6
6
  var exports_auth = {};
@@ -1,12 +1,12 @@
1
1
  import {
2
2
  LocationMiddleware2
3
- } from "./service-status-gymtz25n.js";
3
+ } from "./server-info-50bbk3b2.js";
4
4
  import {
5
5
  FormLocationMiddleware2
6
- } from "./service-status-3154e7fk.js";
6
+ } from "./server-info-htyf2qs7.js";
7
7
  import {
8
8
  SessionLocationMiddleware2
9
- } from "./service-status-x74w7e1f.js";
9
+ } from "./server-info-b3bmdkga.js";
10
10
 
11
11
  // src/api.ts
12
12
  import { makeDefaultApi } from "@opencode/protocol/api";
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  awaitPlugins2,
3
3
  response2
4
- } from "./service-status-gymtz25n.js";
4
+ } from "./server-info-50bbk3b2.js";
5
5
  import {
6
6
  Api2
7
- } from "./service-status-r82dtfrk.js";
7
+ } from "./server-info-j87xz9bt.js";
8
8
 
9
9
  // src/handlers/websearch.ts
10
10
  import { WebSearch } from "@opencode/core/websearch";
@@ -1,25 +1,25 @@
1
1
  import {
2
2
  __export
3
- } from "./service-status-9rqn6x4v.js";
3
+ } from "./server-info-9rqn6x4v.js";
4
4
 
5
5
  // src/pairing.ts
6
6
  var exports_pairing = {};
7
7
  __export(exports_pairing, {
8
8
  ServerPairing: () => exports_pairing,
9
- Service: () => Service3,
10
- node: () => node3
9
+ Service: () => Service2,
10
+ node: () => node2
11
11
  });
12
12
  import { Cache, Context, Duration, Effect, Layer } from "effect";
13
13
  import { makeGlobalNode } from "@opencode/util/effect/app-node";
14
14
  import { randomBytes } from "node:crypto";
15
15
  var TTL = Duration.minutes(5);
16
16
 
17
- class Service3 extends Context.Service()("@opencode/ServerPairing") {
17
+ class Service2 extends Context.Service()("@opencode/ServerPairing") {
18
18
  }
19
19
  var noLookup = () => Effect.die(new Error("ServerPairing cache must be used via set/invalidateWhen, never get"));
20
- var layer = Layer.effect(Service3, Effect.gen(function* () {
20
+ var layer = Layer.effect(Service2, Effect.gen(function* () {
21
21
  const cache = yield* Cache.make({ capacity: 1000, lookup: noLookup, timeToLive: TTL });
22
- return Service3.of({
22
+ return Service2.of({
23
23
  issue: Effect.fn("ServerPairing.issue")(function* () {
24
24
  const code = randomBytes(16).toString("base64url");
25
25
  yield* Cache.set(cache, code, true);
@@ -30,6 +30,6 @@ var layer = Layer.effect(Service3, Effect.gen(function* () {
30
30
  })
31
31
  });
32
32
  }));
33
- var node3 = makeGlobalNode({ service: Service3, layer, deps: [] });
33
+ var node2 = makeGlobalNode({ service: Service2, layer, deps: [] });
34
34
 
35
- export { Service3, node3, exports_pairing };
35
+ export { Service2, node2, exports_pairing };
@@ -0,0 +1,46 @@
1
+ // src/handlers/media.ts
2
+ import { Database } from "@opencode/core/database/database";
3
+ import { SessionBlob } from "@opencode/core/session/blob";
4
+ import { FileNotFoundError } from "@opencode/protocol/errors";
5
+ import { Effect } from "effect";
6
+ import { HttpServerResponse } from "effect/http";
7
+ var INLINE_IMAGE_MIMES = new Set(["image/png", "image/jpeg", "image/gif", "image/webp"]);
8
+ var CACHE_CONTROL = "private, max-age=31536000, immutable";
9
+ var SECURITY_HEADERS = {
10
+ "x-content-type-options": "nosniff",
11
+ "content-security-policy": "default-src 'none'; sandbox"
12
+ };
13
+ var makeMediaGet2 = Effect.gen(function* () {
14
+ const { db } = yield* Database.Service;
15
+ return (hash, request) => Effect.gen(function* () {
16
+ const path = `/api/experimental/media/${hash}`;
17
+ const blob = yield* SessionBlob.read(db, hash);
18
+ if (!blob)
19
+ return yield* new FileNotFoundError({ path, message: `Media blob not found: ${hash}` });
20
+ const etag = `"${hash}"`;
21
+ const inline = INLINE_IMAGE_MIMES.has(blob.mime);
22
+ const headers = {
23
+ "cache-control": CACHE_CONTROL,
24
+ etag,
25
+ ...SECURITY_HEADERS,
26
+ ...inline ? {} : { "content-disposition": "attachment" }
27
+ };
28
+ if (matchesIfNoneMatch(request.headers["if-none-match"], etag))
29
+ return HttpServerResponse.empty({ status: 304, headers });
30
+ return HttpServerResponse.uint8Array(blob.data, {
31
+ status: 200,
32
+ contentType: inline ? blob.mime : "application/octet-stream",
33
+ headers
34
+ });
35
+ });
36
+ });
37
+ function matchesIfNoneMatch(ifNoneMatch, etag) {
38
+ if (ifNoneMatch === undefined)
39
+ return false;
40
+ return ifNoneMatch.split(",").some((tag) => {
41
+ const trimmed = tag.trim();
42
+ return trimmed === "*" || trimmed.replace(/^w\//i, "") === etag;
43
+ });
44
+ }
45
+
46
+ export { makeMediaGet2 };
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  Api2
3
- } from "./service-status-r82dtfrk.js";
3
+ } from "./server-info-j87xz9bt.js";
4
4
  import {
5
5
  Service4,
6
6
  frame2
7
- } from "./service-status-k6dz4enc.js";
7
+ } from "./server-info-s802fzg1.js";
8
8
 
9
9
  // src/handlers/event.ts
10
10
  import { Event } from "@opencode/schema/event";
@@ -13,13 +13,13 @@ import { HttpServerResponse } from "effect/http";
13
13
  import { HttpApiBuilder } from "effect/http-api";
14
14
  var EventHandler2 = HttpApiBuilder.group(Api2, "server.event", (handlers) => Effect.gen(function* () {
15
15
  const feed = yield* Service4;
16
- return handlers.handleRaw("event.subscribe", () => Effect.gen(function* () {
16
+ return handlers.handleRaw("event.subscribe", (ctx) => Effect.gen(function* () {
17
17
  const connected = {
18
18
  id: Event.ID.create(),
19
19
  type: "server.connected",
20
20
  data: {}
21
21
  };
22
- const output = Stream.unwrap(feed.subscribe.pipe(Effect.map((live) => Stream.make(frame2(connected)).pipe(Stream.concat(live)))));
22
+ const output = Stream.unwrap(feed.subscribe(ctx.query.types).pipe(Effect.map((live) => Stream.make(frame2(connected)).pipe(Stream.concat(live)))));
23
23
  const heartbeat = Stream.tick("15 seconds").pipe(Stream.map(() => `: heartbeat
24
24
 
25
25
  `));
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  response2
3
- } from "./service-status-gymtz25n.js";
3
+ } from "./server-info-50bbk3b2.js";
4
4
  import {
5
5
  Api2
6
- } from "./service-status-r82dtfrk.js";
6
+ } from "./server-info-j87xz9bt.js";
7
7
 
8
8
  // src/handlers/skill.ts
9
9
  import { Skill } from "@opencode/core/skill";
@@ -0,0 +1,38 @@
1
+ import {
2
+ requestRef2
3
+ } from "./server-info-50bbk3b2.js";
4
+ import {
5
+ Api2
6
+ } from "./server-info-j87xz9bt.js";
7
+
8
+ // src/handlers/debug.ts
9
+ import { LocationServiceMap } from "@opencode/core/location-service-map";
10
+ import { InvalidRequestError, UnknownError } from "@opencode/protocol/errors";
11
+ import { Global } from "@opencode/util/global";
12
+ import { HeapSnapshot } from "@opencode/util/heap-snapshot";
13
+ import { Effect, Option, RcMap } from "effect";
14
+ import { HttpApiBuilder } from "effect/http-api";
15
+ import path from "node:path";
16
+ var DebugHandler2 = HttpApiBuilder.group(Api2, "server.debug", (handlers) => Effect.gen(function* () {
17
+ const global = yield* Global.Service;
18
+ return handlers.handle("debug.heapDump", Effect.fn("server.debug.heapDump")(function* (ctx) {
19
+ const directory = ctx.query.directory;
20
+ if (directory !== undefined && !path.isAbsolute(directory))
21
+ return yield* new InvalidRequestError({ message: "directory must be an absolute path", field: "directory" });
22
+ return yield* HeapSnapshot.write(directory ?? global.log).pipe(Effect.catch((cause) => {
23
+ const ref = `err_${crypto.randomUUID().slice(0, 8)}`;
24
+ return Effect.logError("failed to write heap snapshot", { cause }).pipe(Effect.annotateLogs({ ref }), Effect.andThen(Effect.fail(new UnknownError({
25
+ message: `Failed to write heap snapshot: ${cause.cause instanceof Error ? cause.cause.message : cause.message}`,
26
+ ref
27
+ }))));
28
+ }));
29
+ })).handle("debug.location", Effect.fn(function* () {
30
+ const locations = Option.getOrThrow(yield* Effect.serviceOption(LocationServiceMap.Service));
31
+ return Array.from(yield* RcMap.keys(locations.rcMap));
32
+ })).handle("debug.location.evict", Effect.fn(function* (ctx) {
33
+ const locations = Option.getOrThrow(yield* Effect.serviceOption(LocationServiceMap.Service));
34
+ yield* locations.invalidate(requestRef2(ctx.request));
35
+ }));
36
+ }));
37
+
38
+ export { DebugHandler2 };
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  response2
3
- } from "./service-status-gymtz25n.js";
3
+ } from "./server-info-50bbk3b2.js";
4
4
  import {
5
5
  Api2
6
- } from "./service-status-r82dtfrk.js";
6
+ } from "./server-info-j87xz9bt.js";
7
7
 
8
8
  // src/handlers/shell.ts
9
9
  import { Shell } from "@opencode/core/shell";
@@ -1,20 +1,20 @@
1
1
  import {
2
2
  awaitPlugins2,
3
3
  response2
4
- } from "./service-status-gymtz25n.js";
4
+ } from "./server-info-50bbk3b2.js";
5
5
  import {
6
6
  Api2
7
- } from "./service-status-r82dtfrk.js";
7
+ } from "./server-info-j87xz9bt.js";
8
8
 
9
9
  // src/handlers/model.ts
10
10
  import { Model } from "@opencode/core/model";
11
11
  import { Effect } from "effect";
12
12
  import { HttpApiBuilder } from "effect/http-api";
13
13
  var ModelHandler2 = HttpApiBuilder.group(Api2, "server.model", (handlers) => Effect.gen(function* () {
14
- return handlers.handle("model.list", Effect.fn(function* () {
14
+ return handlers.handle("model.list", Effect.fn(function* (ctx) {
15
15
  yield* awaitPlugins2;
16
16
  const models = yield* Model.Service;
17
- return yield* response2(models.available());
17
+ return yield* response2(models.available(ctx.query.types));
18
18
  })).handle("model.default", Effect.fn(function* () {
19
19
  yield* awaitPlugins2;
20
20
  const models = yield* Model.Service;
@@ -1,13 +1,16 @@
1
1
  import {
2
2
  Api2
3
- } from "./service-status-r82dtfrk.js";
3
+ } from "./server-info-j87xz9bt.js";
4
4
  import {
5
5
  CorsConfig2,
6
6
  isAllowedRequestOrigin2
7
- } from "./service-status-q4bn6dy8.js";
7
+ } from "./server-info-q4bn6dy8.js";
8
+ import {
9
+ makeMediaGet2
10
+ } from "./server-info-n321d8vm.js";
8
11
  import {
9
12
  runPtySocket2
10
- } from "./service-status-h6rt5k9s.js";
13
+ } from "./server-info-h6rt5k9s.js";
11
14
 
12
15
  // src/handlers/persistent-pty.ts
13
16
  import { PersistentPty } from "@opencode/core/persistent-pty";
@@ -26,7 +29,8 @@ var PersistentPtyHandler2 = HttpApiBuilder.group(Api2, "server.experimental", (h
26
29
  const tickets = yield* PtyTicket.Service;
27
30
  const cors = yield* CorsConfig2;
28
31
  const pty = yield* PersistentPty.Service;
29
- return handlers.handle("persistentPty.read", Effect.fn(function* (ctx) {
32
+ const mediaGet = yield* makeMediaGet2;
33
+ return handlers.handleRaw("media.get", (ctx) => mediaGet(ctx.params.hash, ctx.request)).handle("persistentPty.read", Effect.fn(function* (ctx) {
30
34
  return { data: yield* pty.read(ctx.params.sessionID, ctx.query.lines).pipe(mapUnavailable) };
31
35
  })).handle("persistentPty.list", Effect.fn(function* (ctx) {
32
36
  return { data: yield* pty.list(ctx.params.sessionID).pipe(mapUnavailable) };