@opencode/server 2.1.4 → 2.2.1

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 (126) hide show
  1. package/dist/api.d.ts +8 -1
  2. package/dist/api.js +5 -5
  3. package/dist/auth.js +1 -1
  4. package/dist/chunks/{pairing-e4x9285j.js → media-uri-0a5jm2na.js} +4 -4
  5. package/dist/chunks/{pairing-0dncng21.js → media-uri-0n1e9dnh.js} +25 -12
  6. package/dist/chunks/{pairing-x0608mvx.js → media-uri-1je14sn4.js} +1 -1
  7. package/dist/chunks/{pairing-2yr2dq97.js → media-uri-22wspztn.js} +2 -2
  8. package/dist/chunks/{pairing-5w10ccet.js → media-uri-2xcc0x05.js} +1 -1
  9. package/dist/chunks/{pairing-39nnfjx1.js → media-uri-39nnfjx1.js} +1 -1
  10. package/dist/chunks/{pairing-x2dckmx1.js → media-uri-3t6z87e1.js} +23 -16
  11. package/dist/chunks/{pairing-4b0899hb.js → media-uri-6vs5sqy6.js} +2 -2
  12. package/dist/chunks/{pairing-7b9xm1qg.js → media-uri-7b9xm1qg.js} +1 -1
  13. package/dist/chunks/{pairing-aj1jc7g7.js → media-uri-8113w26k.js} +8 -6
  14. package/dist/chunks/{pairing-t3j5ftv1.js → media-uri-9c4eyh8m.js} +3 -3
  15. package/dist/chunks/{pairing-3te71694.js → media-uri-b1prsepx.js} +4 -4
  16. package/dist/chunks/{pairing-e7pctymn.js → media-uri-b2k9041j.js} +1 -1
  17. package/dist/chunks/{pairing-erzfdgke.js → media-uri-bd8755ek.js} +16 -1
  18. package/dist/chunks/{pairing-f4b2q3tn.js → media-uri-be53s2qz.js} +1 -1
  19. package/dist/chunks/media-uri-c6sjpm0r.js +83 -0
  20. package/dist/chunks/{pairing-4qjw9nya.js → media-uri-ckkpcd9y.js} +4 -4
  21. package/dist/chunks/{pairing-j5aeaa16.js → media-uri-dk68ymtv.js} +1 -1
  22. package/dist/chunks/{pairing-kcjd09wg.js → media-uri-e46y0tfd.js} +2 -2
  23. package/dist/chunks/{pairing-k6dz4enc.js → media-uri-fvpjvjpp.js} +24 -23
  24. package/dist/chunks/{pairing-3154e7fk.js → media-uri-gk0yxcp6.js} +5 -3
  25. package/dist/chunks/{pairing-gymtz25n.js → media-uri-gqq6kfhc.js} +3 -3
  26. package/dist/chunks/{pairing-cfhthk6z.js → media-uri-h072q2hm.js} +1 -1
  27. package/dist/chunks/{pairing-a6kxe6a7.js → media-uri-h3g82chs.js} +12 -4
  28. package/dist/chunks/{pairing-2b2wekgg.js → media-uri-h9rcwvg0.js} +1 -1
  29. package/dist/chunks/{pairing-swdgbzpj.js → media-uri-hax1v4bv.js} +4 -2
  30. package/dist/chunks/{pairing-ga3m49sz.js → media-uri-hnheq3hv.js} +4 -2
  31. package/dist/chunks/{pairing-j4at0y5c.js → media-uri-j4at0y5c.js} +1 -1
  32. package/dist/chunks/media-uri-j9gxd9me.js +22 -0
  33. package/dist/chunks/{pairing-91mt6ewz.js → media-uri-m5rae7m4.js} +2 -2
  34. package/dist/chunks/{pairing-kqr36gas.js → media-uri-mzs0n5xz.js} +7 -7
  35. package/dist/chunks/media-uri-n321d8vm.js +46 -0
  36. package/dist/chunks/media-uri-ndydfxzp.js +105 -0
  37. package/dist/chunks/{pairing-6xea6nhh.js → media-uri-ppma8fcc.js} +3 -3
  38. package/dist/chunks/{pairing-qvy2s3nb.js → media-uri-prdak4hd.js} +6 -6
  39. package/dist/chunks/{pairing-mte34432.js → media-uri-qbhbayp5.js} +3 -3
  40. package/dist/chunks/{pairing-49c878v9.js → media-uri-qn8kkfq6.js} +12 -3
  41. package/dist/chunks/{pairing-x9vr2ttf.js → media-uri-r6vmgwff.js} +24 -6
  42. package/dist/chunks/{pairing-9me4q8wt.js → media-uri-rztv1fyf.js} +4 -4
  43. package/dist/chunks/{pairing-nv8hzzrz.js → media-uri-wd7b20jw.js} +32 -12
  44. package/dist/chunks/{pairing-kaqtndqt.js → media-uri-wxj3d9av.js} +4 -11
  45. package/dist/chunks/{pairing-q69f22pd.js → media-uri-x8dgc261.js} +2 -2
  46. package/dist/chunks/{pairing-31acg4hb.js → media-uri-xe9t9xr4.js} +7 -3
  47. package/dist/chunks/media-uri-xthc02cw.js +6 -0
  48. package/dist/chunks/media-uri-xzvdbbpy.js +40 -0
  49. package/dist/chunks/{pairing-x74w7e1f.js → media-uri-yet0vexm.js} +1 -1
  50. package/dist/chunks/{pairing-kd6vzpgq.js → media-uri-yr4wsvrw.js} +2 -2
  51. package/dist/chunks/{pairing-xmwystkq.js → media-uri-z59gyc0x.js} +2 -2
  52. package/dist/chunks/{pairing-72ygafj3.js → media-uri-zjy4sw3d.js} +2 -2
  53. package/dist/cors.js +1 -1
  54. package/dist/event-feed.d.ts +1 -1
  55. package/dist/event-feed.js +5 -5
  56. package/dist/fetch.js +51 -47
  57. package/dist/handlers/agent.js +6 -6
  58. package/dist/handlers/command.js +6 -6
  59. package/dist/handlers/config.js +6 -6
  60. package/dist/handlers/credential.js +6 -6
  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.js +8 -8
  71. package/dist/handlers/media.d.ts +6 -0
  72. package/dist/handlers/media.js +6 -0
  73. package/dist/handlers/message.js +7 -6
  74. package/dist/handlers/migration.js +6 -6
  75. package/dist/handlers/model.js +6 -6
  76. package/dist/handlers/permission.js +6 -6
  77. package/dist/handlers/persistent-pty.d.ts +1 -1
  78. package/dist/handlers/persistent-pty.js +10 -8
  79. package/dist/handlers/plugin.js +6 -6
  80. package/dist/handlers/project.d.ts +1 -1
  81. package/dist/handlers/project.js +6 -6
  82. package/dist/handlers/provider.js +6 -6
  83. package/dist/handlers/pty-socket.js +1 -1
  84. package/dist/handlers/pty.js +8 -8
  85. package/dist/handlers/reference.js +6 -6
  86. package/dist/handlers/rpc.js +6 -6
  87. package/dist/handlers/schedule.d.ts +209 -0
  88. package/dist/handlers/schedule.js +7 -0
  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 +47 -43
  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 +3 -3
  112. package/dist/process.js +55 -49
  113. package/dist/request-tracing.js +1 -1
  114. package/dist/routes.d.ts +5 -2
  115. package/dist/routes.js +50 -46
  116. package/dist/server-info.js +3 -3
  117. package/dist/service-status.js +1 -1
  118. package/dist/workerd.js +52 -48
  119. package/package.json +9 -8
  120. package/dist/chunks/pairing-kyxm98pg.js +0 -102
  121. package/dist/chunks/pairing-pmjbkszz.js +0 -30
  122. /package/dist/chunks/{pairing-9rqn6x4v.js → media-uri-9rqn6x4v.js} +0 -0
  123. /package/dist/chunks/{pairing-h6rt5k9s.js → media-uri-h6rt5k9s.js} +0 -0
  124. /package/dist/chunks/{pairing-q4bn6dy8.js → media-uri-q4bn6dy8.js} +0 -0
  125. /package/dist/chunks/{pairing-smaf4a18.js → media-uri-smaf4a18.js} +0 -0
  126. /package/dist/chunks/{pairing-yc7nft6q.js → media-uri-yc7nft6q.js} +0 -0
@@ -1,17 +1,17 @@
1
1
  import {
2
2
  __export
3
- } from "./pairing-9rqn6x4v.js";
3
+ } from "./media-uri-9rqn6x4v.js";
4
4
 
5
5
  // src/event-feed.ts
6
6
  var exports_event_feed = {};
7
7
  __export(exports_event_feed, {
8
8
  EncodingError: () => EncodingError2,
9
9
  EventFeed: () => exports_event_feed,
10
- Service: () => Service4,
10
+ Service: () => Service2,
11
11
  SubscriberCapacity: () => SubscriberCapacity2,
12
12
  SubscriberOverflowError: () => SubscriberOverflowError2,
13
13
  frame: () => frame2,
14
- layer: () => layer4,
14
+ layer: () => layer2,
15
15
  make: () => make4
16
16
  });
17
17
  import { Bus } from "@opencode/core/bus";
@@ -30,7 +30,7 @@ class EncodingError2 extends Schema.TaggedError()("EventFeed.EncodingError", {
30
30
  }) {
31
31
  }
32
32
 
33
- class Service4 extends Context.Service()("@opencode/server/EventFeed") {
33
+ class Service2 extends Context.Service()("@opencode/server/EventFeed") {
34
34
  }
35
35
  function frame2(event) {
36
36
  return `data: ${JSON.stringify(event)}
@@ -40,9 +40,9 @@ function frame2(event) {
40
40
  var make4 = Effect.fn("EventFeed.make")(function* (observe, options) {
41
41
  const capacity = options?.capacity ?? SubscriberCapacity2;
42
42
  const render = options?.encode ?? frame2;
43
- const subscribers = new Set;
43
+ const subscribers = new Map;
44
44
  const fail = (error) => Effect.sync(() => {
45
- const current = Array.from(subscribers);
45
+ const current = Array.from(subscribers.keys());
46
46
  subscribers.clear();
47
47
  for (const subscriber of current)
48
48
  Queue.failCauseUnsafe(subscriber, Cause.fail(error));
@@ -50,19 +50,20 @@ var make4 = Effect.fn("EventFeed.make")(function* (observe, options) {
50
50
  const publish = Effect.fnUntraced(function* (event) {
51
51
  if (!isOpenCodeEvent(event))
52
52
  return;
53
- if (subscribers.size === 0)
54
- return;
55
- const encoded = yield* Effect.try({
56
- try: () => render(event),
57
- catch: (cause) => new EncodingError2({ eventID: event.id, eventType: event.type, cause })
58
- }).pipe(Effect.catch((error) => Effect.logError("Failed to encode public event", {
59
- eventID: error.eventID,
60
- eventType: error.eventType,
61
- cause: error.cause
62
- }).pipe(Effect.andThen(fail(error)), Effect.as(undefined))));
63
- if (encoded === undefined)
64
- return;
65
- for (const subscriber of subscribers) {
53
+ let encoded;
54
+ for (const [subscriber, types] of subscribers) {
55
+ if (types && !types.has(event.type))
56
+ continue;
57
+ encoded ??= yield* Effect.try({
58
+ try: () => render(event),
59
+ catch: (cause) => new EncodingError2({ eventID: event.id, eventType: event.type, cause })
60
+ }).pipe(Effect.catch((error) => Effect.logError("Failed to encode public event", {
61
+ eventID: error.eventID,
62
+ eventType: error.eventType,
63
+ cause: error.cause
64
+ }).pipe(Effect.andThen(fail(error)), Effect.as(undefined))));
65
+ if (encoded === undefined)
66
+ return;
66
67
  if (Queue.offerUnsafe(subscriber, encoded))
67
68
  continue;
68
69
  subscribers.delete(subscriber);
@@ -71,13 +72,13 @@ var make4 = Effect.fn("EventFeed.make")(function* (observe, options) {
71
72
  });
72
73
  const unsubscribe = yield* observe(publish);
73
74
  yield* Effect.addFinalizer(() => unsubscribe);
74
- return Service4.of({
75
- subscribe: Effect.acquireRelease(Queue.dropping(capacity).pipe(Effect.tap((queue) => Effect.sync(() => subscribers.add(queue)))), (queue) => Effect.sync(() => subscribers.delete(queue)).pipe(Effect.andThen(Queue.shutdown(queue)), Effect.asVoid)).pipe(Effect.map(Stream.fromQueue))
75
+ return Service2.of({
76
+ subscribe: (types) => Effect.acquireRelease(Queue.dropping(capacity).pipe(Effect.tap((queue) => Effect.sync(() => subscribers.set(queue, types?.length ? new Set(types) : undefined)))), (queue) => Effect.sync(() => subscribers.delete(queue)).pipe(Effect.andThen(Queue.shutdown(queue)), Effect.asVoid)).pipe(Effect.map(Stream.fromQueue))
76
77
  });
77
78
  });
78
- var layer4 = Layer.effect(Service4, Effect.gen(function* () {
79
+ var layer2 = Layer.effect(Service2, Effect.gen(function* () {
79
80
  const bus = yield* Bus.Service;
80
81
  return yield* make4(bus.listen);
81
82
  }));
82
83
 
83
- export { SubscriberCapacity2, SubscriberOverflowError2, EncodingError2, Service4, frame2, make4, layer4, exports_event_feed };
84
+ export { SubscriberCapacity2, SubscriberOverflowError2, EncodingError2, Service2, frame2, make4, layer2, exports_event_feed };
@@ -2,7 +2,7 @@ import {
2
2
  locationErrors2,
3
3
  sessionInfo2,
4
4
  requestRef2
5
- } from "./pairing-gymtz25n.js";
5
+ } from "./media-uri-gqq6kfhc.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,6 +1,6 @@
1
1
  import {
2
2
  missingSession2
3
- } from "./pairing-smaf4a18.js";
3
+ } from "./media-uri-smaf4a18.js";
4
4
 
5
5
  // src/location.ts
6
6
  import { FileSystem } from "@opencode/core/filesystem";
@@ -59,7 +59,7 @@ function decode(input) {
59
59
  return input;
60
60
  }
61
61
  }
62
- var layer2 = Layer.effect(LocationMiddleware2, Effect.gen(function* () {
62
+ var layer3 = Layer.effect(LocationMiddleware2, Effect.gen(function* () {
63
63
  const locations = yield* LocationServiceMap.Service;
64
64
  return LocationMiddleware2.of((effect) => Effect.gen(function* () {
65
65
  const request = yield* HttpServerRequest.HttpServerRequest;
@@ -67,4 +67,4 @@ var layer2 = Layer.effect(LocationMiddleware2, Effect.gen(function* () {
67
67
  }));
68
68
  }));
69
69
 
70
- export { LocationMiddleware2, locationErrors2, awaitPlugins2, response2, sessionInfo2, requestRef2, layer2 };
70
+ export { LocationMiddleware2, locationErrors2, awaitPlugins2, response2, sessionInfo2, requestRef2, layer3 };
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  Api2
3
- } from "./pairing-t3j5ftv1.js";
3
+ } from "./media-uri-9c4eyh8m.js";
4
4
 
5
5
  // src/handlers/location.ts
6
6
  import { Location } from "@opencode/core/location";
@@ -1,13 +1,19 @@
1
1
  import {
2
2
  Api2
3
- } from "./pairing-t3j5ftv1.js";
3
+ } from "./media-uri-9c4eyh8m.js";
4
4
  import {
5
5
  CorsConfig2,
6
6
  isAllowedRequestOrigin2
7
- } from "./pairing-q4bn6dy8.js";
7
+ } from "./media-uri-q4bn6dy8.js";
8
+ import {
9
+ makeMediaGet2
10
+ } from "./media-uri-n321d8vm.js";
8
11
  import {
9
12
  runPtySocket2
10
- } from "./pairing-h6rt5k9s.js";
13
+ } from "./media-uri-h6rt5k9s.js";
14
+ import {
15
+ makeSchedule2
16
+ } from "./media-uri-xzvdbbpy.js";
11
17
 
12
18
  // src/handlers/persistent-pty.ts
13
19
  import { PersistentPty } from "@opencode/core/persistent-pty";
@@ -26,7 +32,9 @@ var PersistentPtyHandler2 = HttpApiBuilder.group(Api2, "server.experimental", (h
26
32
  const tickets = yield* PtyTicket.Service;
27
33
  const cors = yield* CorsConfig2;
28
34
  const pty = yield* PersistentPty.Service;
29
- return handlers.handle("persistentPty.read", Effect.fn(function* (ctx) {
35
+ const mediaGet = yield* makeMediaGet2;
36
+ const schedule = yield* makeSchedule2;
37
+ return handlers.handleRaw("media.get", (ctx) => mediaGet(ctx.params.hash, ctx.request)).handle("schedule.create", (ctx) => schedule.create(ctx.payload)).handle("schedule.list", (ctx) => schedule.list(ctx.query.sessionID)).handle("schedule.get", (ctx) => schedule.get(ctx.params.scheduleID)).handle("schedule.pause", (ctx) => schedule.pause(ctx.params.scheduleID)).handle("schedule.resume", (ctx) => schedule.resume(ctx.params.scheduleID)).handle("schedule.delete", (ctx) => schedule.remove(ctx.params.scheduleID)).handle("persistentPty.read", Effect.fn(function* (ctx) {
30
38
  return { data: yield* pty.read(ctx.params.sessionID, ctx.query.lines).pipe(mapUnavailable) };
31
39
  })).handle("persistentPty.list", Effect.fn(function* (ctx) {
32
40
  return { data: yield* pty.list(ctx.params.sessionID).pipe(mapUnavailable) };
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  Api2
3
- } from "./pairing-t3j5ftv1.js";
3
+ } from "./media-uri-9c4eyh8m.js";
4
4
 
5
5
  // src/handlers/worktree.ts
6
6
  import { Git } from "@opencode/core/git";
@@ -1,9 +1,10 @@
1
1
  import {
2
+ awaitPlugins2,
2
3
  response2
3
- } from "./pairing-gymtz25n.js";
4
+ } from "./media-uri-gqq6kfhc.js";
4
5
  import {
5
6
  Api2
6
- } from "./pairing-t3j5ftv1.js";
7
+ } from "./media-uri-9c4eyh8m.js";
7
8
 
8
9
  // src/handlers/provider.ts
9
10
  import { Provider } from "@opencode/core/provider";
@@ -12,6 +13,7 @@ import { Effect } from "effect";
12
13
  import { HttpApiBuilder } from "effect/http-api";
13
14
  var ProviderHandler2 = HttpApiBuilder.group(Api2, "server.provider", (handlers) => Effect.gen(function* () {
14
15
  return handlers.handle("provider.list", Effect.fn(function* () {
16
+ yield* awaitPlugins2;
15
17
  const providers = yield* Provider.Service;
16
18
  return yield* response2(providers.available());
17
19
  })).handle("provider.get", Effect.fn(function* (ctx) {
@@ -1,9 +1,10 @@
1
1
  import {
2
+ awaitPlugins2,
2
3
  response2
3
- } from "./pairing-gymtz25n.js";
4
+ } from "./media-uri-gqq6kfhc.js";
4
5
  import {
5
6
  Api2
6
- } from "./pairing-t3j5ftv1.js";
7
+ } from "./media-uri-9c4eyh8m.js";
7
8
 
8
9
  // src/handlers/agent.ts
9
10
  import { Agent } from "@opencode/core/agent";
@@ -11,6 +12,7 @@ import { Effect } from "effect";
11
12
  import { HttpApiBuilder } from "effect/http-api";
12
13
  import { AgentNotFoundError } from "@opencode/protocol/errors";
13
14
  var AgentHandler2 = HttpApiBuilder.group(Api2, "server.agent", (handlers) => handlers.handle("agent.list", () => Effect.gen(function* () {
15
+ yield* awaitPlugins2;
14
16
  return yield* response2(Agent.Service.use((agent) => agent.list()));
15
17
  })).handle("agent.get", Effect.fn(function* (ctx) {
16
18
  const agent = yield* Agent.Service.use((service) => service.get(ctx.params.agentID));
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  __export
3
- } from "./pairing-9rqn6x4v.js";
3
+ } from "./media-uri-9rqn6x4v.js";
4
4
 
5
5
  // src/auth.ts
6
6
  var exports_auth = {};
@@ -0,0 +1,22 @@
1
+ import {
2
+ awaitPlugins2,
3
+ response2
4
+ } from "./media-uri-gqq6kfhc.js";
5
+ import {
6
+ Api2
7
+ } from "./media-uri-9c4eyh8m.js";
8
+
9
+ // src/handlers/usage.ts
10
+ import { UsageLimits } from "@opencode/core/usage-limits";
11
+ import { ServiceUnavailableError } from "@opencode/protocol/errors";
12
+ import { Effect } from "effect";
13
+ import { HttpApiBuilder } from "effect/http-api";
14
+ var UsageHandler2 = HttpApiBuilder.group(Api2, "server.usage", (handlers) => Effect.gen(function* () {
15
+ return handlers.handle("usage.limits", Effect.fn("server.usage.limits")(function* () {
16
+ yield* awaitPlugins2;
17
+ const limits = yield* UsageLimits.Service;
18
+ return yield* response2(limits.get().pipe(Effect.map((info) => info ?? null), Effect.mapError((error) => new ServiceUnavailableError({ message: error.message, service: "opencode" }))));
19
+ }));
20
+ }));
21
+
22
+ export { UsageHandler2 };
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  response2
3
- } from "./pairing-gymtz25n.js";
3
+ } from "./media-uri-gqq6kfhc.js";
4
4
  import {
5
5
  Api2
6
- } from "./pairing-t3j5ftv1.js";
6
+ } from "./media-uri-9c4eyh8m.js";
7
7
 
8
8
  // src/handlers/form.ts
9
9
  import { Form } from "@opencode/core/form";
@@ -1,12 +1,12 @@
1
1
  import {
2
2
  __export
3
- } from "./pairing-9rqn6x4v.js";
3
+ } from "./media-uri-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: () => Service2,
9
+ Service: () => Service4,
10
10
  node: () => node2
11
11
  });
12
12
  import { Cache, Context, Duration, Effect, Layer } from "effect";
@@ -14,12 +14,12 @@ 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 Service2 extends Context.Service()("@opencode/ServerPairing") {
17
+ class Service4 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(Service2, Effect.gen(function* () {
20
+ var layer = Layer.effect(Service4, Effect.gen(function* () {
21
21
  const cache = yield* Cache.make({ capacity: 1000, lookup: noLookup, timeToLive: TTL });
22
- return Service2.of({
22
+ return Service4.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(Service2, Effect.gen(function* () {
30
30
  })
31
31
  });
32
32
  }));
33
- var node2 = makeGlobalNode({ service: Service2, layer, deps: [] });
33
+ var node2 = makeGlobalNode({ service: Service4, layer, deps: [] });
34
34
 
35
- export { Service2, node2, exports_pairing };
35
+ export { Service4, 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 };
@@ -0,0 +1,105 @@
1
+ import {
2
+ GenerateHandler2
3
+ } from "./media-uri-c6sjpm0r.js";
4
+ import {
5
+ VoiceHandler2
6
+ } from "./media-uri-wxj3d9av.js";
7
+ import {
8
+ MessageHandler2
9
+ } from "./media-uri-0n1e9dnh.js";
10
+ import {
11
+ ModelHandler2
12
+ } from "./media-uri-0a5jm2na.js";
13
+ import {
14
+ ProviderHandler2
15
+ } from "./media-uri-hax1v4bv.js";
16
+ import {
17
+ SessionHandler2
18
+ } from "./media-uri-wd7b20jw.js";
19
+ import {
20
+ PermissionHandler2
21
+ } from "./media-uri-ppma8fcc.js";
22
+ import {
23
+ FileSystemHandler2
24
+ } from "./media-uri-r6vmgwff.js";
25
+ import {
26
+ FormHandler2
27
+ } from "./media-uri-m5rae7m4.js";
28
+ import {
29
+ CommandHandler2
30
+ } from "./media-uri-z59gyc0x.js";
31
+ import {
32
+ SkillHandler2
33
+ } from "./media-uri-6vs5sqy6.js";
34
+ import {
35
+ RpcHandler2
36
+ } from "./media-uri-2xcc0x05.js";
37
+ import {
38
+ layer2
39
+ } from "./media-uri-fvpjvjpp.js";
40
+ import {
41
+ EventHandler2
42
+ } from "./media-uri-prdak4hd.js";
43
+ import {
44
+ AgentHandler2
45
+ } from "./media-uri-hnheq3hv.js";
46
+ import {
47
+ PluginHandler2
48
+ } from "./media-uri-qn8kkfq6.js";
49
+ import {
50
+ ServerHandler2
51
+ } from "./media-uri-8113w26k.js";
52
+ import {
53
+ DebugHandler2
54
+ } from "./media-uri-x8dgc261.js";
55
+ import {
56
+ PtyHandler2
57
+ } from "./media-uri-ckkpcd9y.js";
58
+ import {
59
+ PersistentPtyHandler2
60
+ } from "./media-uri-h3g82chs.js";
61
+ import {
62
+ ShellHandler2
63
+ } from "./media-uri-22wspztn.js";
64
+ import {
65
+ ReferenceHandler2
66
+ } from "./media-uri-yr4wsvrw.js";
67
+ import {
68
+ LocationHandler2
69
+ } from "./media-uri-h072q2hm.js";
70
+ import {
71
+ IntegrationHandler2
72
+ } from "./media-uri-zjy4sw3d.js";
73
+ import {
74
+ WebSearchHandler2
75
+ } from "./media-uri-e46y0tfd.js";
76
+ import {
77
+ UsageHandler2
78
+ } from "./media-uri-j9gxd9me.js";
79
+ import {
80
+ McpHandler2
81
+ } from "./media-uri-rztv1fyf.js";
82
+ import {
83
+ CredentialHandler2
84
+ } from "./media-uri-be53s2qz.js";
85
+ import {
86
+ ProjectHandler2
87
+ } from "./media-uri-dk68ymtv.js";
88
+ import {
89
+ WorktreeHandler2
90
+ } from "./media-uri-h9rcwvg0.js";
91
+ import {
92
+ VcsHandler2
93
+ } from "./media-uri-xe9t9xr4.js";
94
+ import {
95
+ MigrationHandler2
96
+ } from "./media-uri-1je14sn4.js";
97
+ import {
98
+ ConfigHandler2
99
+ } from "./media-uri-b2k9041j.js";
100
+
101
+ // src/handlers.ts
102
+ import { Layer } from "effect";
103
+ var handlers2 = Layer.mergeAll(ServerHandler2, DebugHandler2, MigrationHandler2, LocationHandler2, AgentHandler2, PluginHandler2, SessionHandler2, MessageHandler2, ModelHandler2, GenerateHandler2, VoiceHandler2, ProviderHandler2, IntegrationHandler2, WebSearchHandler2, UsageHandler2, McpHandler2, CredentialHandler2, ProjectHandler2, FormHandler2, PermissionHandler2, FileSystemHandler2, CommandHandler2, SkillHandler2, RpcHandler2, EventHandler2.pipe(Layer.provide(layer2)), PtyHandler2, PersistentPtyHandler2, ShellHandler2, ReferenceHandler2, WorktreeHandler2, VcsHandler2, ConfigHandler2);
104
+
105
+ export { handlers2 };
@@ -1,14 +1,14 @@
1
1
  import {
2
2
  missingSession2
3
- } from "./pairing-smaf4a18.js";
3
+ } from "./media-uri-smaf4a18.js";
4
4
  import {
5
5
  locationErrors2,
6
6
  response2,
7
7
  sessionInfo2
8
- } from "./pairing-gymtz25n.js";
8
+ } from "./media-uri-gqq6kfhc.js";
9
9
  import {
10
10
  Api2
11
- } from "./pairing-t3j5ftv1.js";
11
+ } from "./media-uri-9c4eyh8m.js";
12
12
 
13
13
  // src/handlers/permission.ts
14
14
  import { Instance } from "@opencode/core/instance/service";
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  Api2
3
- } from "./pairing-t3j5ftv1.js";
3
+ } from "./media-uri-9c4eyh8m.js";
4
4
  import {
5
- Service4,
5
+ Service2,
6
6
  frame2
7
- } from "./pairing-k6dz4enc.js";
7
+ } from "./media-uri-fvpjvjpp.js";
8
8
 
9
9
  // src/handlers/event.ts
10
10
  import { Event } from "@opencode/schema/event";
@@ -12,14 +12,14 @@ import { Effect, Stream } from "effect";
12
12
  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
- const feed = yield* Service4;
16
- return handlers.handleRaw("event.subscribe", () => Effect.gen(function* () {
15
+ const feed = yield* Service2;
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,12 +1,12 @@
1
1
  import {
2
2
  isAllowedCorsOrigin2
3
- } from "./pairing-q4bn6dy8.js";
3
+ } from "./media-uri-q4bn6dy8.js";
4
4
  import {
5
5
  createRoutes2
6
- } from "./pairing-x2dckmx1.js";
6
+ } from "./media-uri-3t6z87e1.js";
7
7
  import {
8
8
  __export
9
- } from "./pairing-9rqn6x4v.js";
9
+ } from "./media-uri-9rqn6x4v.js";
10
10
 
11
11
  // src/fetch.ts
12
12
  var exports_fetch = {};
@@ -1,18 +1,27 @@
1
1
  import {
2
2
  response2
3
- } from "./pairing-gymtz25n.js";
3
+ } from "./media-uri-gqq6kfhc.js";
4
4
  import {
5
5
  Api2
6
- } from "./pairing-t3j5ftv1.js";
6
+ } from "./media-uri-9c4eyh8m.js";
7
7
 
8
8
  // src/handlers/plugin.ts
9
9
  import { Plugin } from "@opencode/core/plugin";
10
10
  import { PluginUpdate } from "@opencode/core/plugin/update";
11
- import { InvalidRequestError, ServiceUnavailableError } from "@opencode/protocol/errors";
11
+ import { InvalidRequestError, PluginNotFoundError, ServiceUnavailableError } from "@opencode/protocol/errors";
12
12
  import { Cause, Effect, Exit } from "effect";
13
13
  import { HttpApiBuilder } from "effect/http-api";
14
14
  var PluginHandler2 = HttpApiBuilder.group(Api2, "server.plugin", (handlers) => handlers.handle("plugin.list", () => Effect.gen(function* () {
15
15
  return yield* response2(Plugin.Service.use((plugin) => plugin.list()));
16
+ })).handle("plugin.gui", (ctx) => Effect.gen(function* () {
17
+ const plugins = yield* Plugin.Service;
18
+ const bundle = yield* plugins.gui(ctx.query.id);
19
+ if (!bundle)
20
+ return yield* new PluginNotFoundError({
21
+ pluginID: ctx.query.id,
22
+ message: `No active plugin with a ./gui-experimental bundle: ${ctx.query.id}`
23
+ });
24
+ return yield* response2(Effect.succeed(bundle));
16
25
  })).handle("plugin.check", (ctx) => Effect.gen(function* () {
17
26
  const plugins = yield* Plugin.Service;
18
27
  const inventory = yield* plugins.list();
@@ -1,22 +1,26 @@
1
1
  import {
2
2
  response2
3
- } from "./pairing-gymtz25n.js";
3
+ } from "./media-uri-gqq6kfhc.js";
4
4
  import {
5
5
  Api2
6
- } from "./pairing-t3j5ftv1.js";
6
+ } from "./media-uri-9c4eyh8m.js";
7
7
 
8
8
  // src/handlers/fs.ts
9
9
  import { FileSystem } from "@opencode/core/filesystem";
10
+ import { FileWatch } from "@opencode/core/filesystem/file-watch";
11
+ import { Location } from "@opencode/core/location";
10
12
  import { RelativePath } from "@opencode/core/schema";
11
- import { FileNotFoundError } from "@opencode/protocol/errors";
13
+ import { FileNotFoundError, ServiceUnavailableError } from "@opencode/protocol/errors";
12
14
  import { Effect, Option, Stream } from "effect";
13
15
  import { HttpServerResponse } from "effect/http";
14
16
  import { HttpApiBuilder } from "effect/http-api";
17
+ import path from "path";
15
18
  var FileSystemHandler2 = HttpApiBuilder.group(Api2, "server.fs", (handlers) => Effect.gen(function* () {
19
+ const fileWatch = yield* FileWatch.Service;
16
20
  return handlers.handleRaw("fs.read", (ctx) => Effect.gen(function* () {
17
- const path = yield* decodeRequestPath(ctx.request.url);
21
+ const path2 = yield* decodeRequestPath(ctx.request.url);
18
22
  const fs = yield* FileSystem.Service;
19
- const file = yield* fs.read({ path }).pipe(Effect.mapError((error) => new FileNotFoundError({ path: error.path, message: `File not found: ${error.path}` })));
23
+ const file = yield* fs.read({ path: path2 }).pipe(Effect.mapError((error) => new FileNotFoundError({ path: error.path, message: `File not found: ${error.path}` })));
20
24
  return serveFile(ctx.request, file);
21
25
  })).handle("fs.list", (ctx) => response2(Effect.gen(function* () {
22
26
  const fs = yield* FileSystem.Service;
@@ -27,7 +31,21 @@ var FileSystemHandler2 = HttpApiBuilder.group(Api2, "server.fs", (handlers) => E
27
31
  }))).handle("fs.write", (ctx) => response2(Effect.gen(function* () {
28
32
  const fs = yield* FileSystem.Service;
29
33
  return yield* fs.write({ path: ctx.query.path, data: ctx.payload });
30
- })));
34
+ }))).handle("fs.watch", (ctx) => Effect.gen(function* () {
35
+ const fs = yield* FileSystem.Service;
36
+ const location = yield* Location.Service;
37
+ yield* fs.read({ path: RelativePath.make(ctx.payload.path) }).pipe(Effect.mapError((error) => new FileNotFoundError({ path: error.path, message: `File not found: ${error.path}` })));
38
+ yield* fileWatch.watch({
39
+ location: { directory: location.directory, workspaceID: location.workspaceID },
40
+ file: path.resolve(location.directory, ctx.payload.path)
41
+ }).pipe(Effect.mapError((error) => new ServiceUnavailableError({ message: error.message, service: "filewatcher" })));
42
+ })).handle("fs.unwatch", (ctx) => Effect.gen(function* () {
43
+ const location = yield* Location.Service;
44
+ yield* fileWatch.unwatch({
45
+ location: { directory: location.directory, workspaceID: location.workspaceID },
46
+ file: path.resolve(location.directory, ctx.payload.path)
47
+ });
48
+ }));
31
49
  }));
32
50
  function decodeRequestPath(url) {
33
51
  const raw = new URL(url, "http://localhost").pathname.slice(13);