@opencode/server 2.1.3 → 2.1.4

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 (113) hide show
  1. package/dist/api.d.ts +846 -968
  2. package/dist/api.js +5 -5
  3. package/dist/auth.js +1 -1
  4. package/dist/chunks/{service-status-j3461ttv.js → pairing-0dncng21.js} +6 -9
  5. package/dist/chunks/{service-status-6tj91hdj.js → pairing-2b2wekgg.js} +3 -3
  6. package/dist/chunks/{service-status-6e6jjne7.js → pairing-2yr2dq97.js} +2 -2
  7. package/dist/chunks/{service-status-3154e7fk.js → pairing-3154e7fk.js} +1 -1
  8. package/dist/chunks/{service-status-1qc831kp.js → pairing-31acg4hb.js} +2 -2
  9. package/dist/chunks/{service-status-e6e4kz0w.js → pairing-39nnfjx1.js} +4 -4
  10. package/dist/chunks/{service-status-x2cwbfak.js → pairing-3te71694.js} +7 -7
  11. package/dist/chunks/{service-status-jwf0kwqx.js → pairing-49c878v9.js} +2 -2
  12. package/dist/chunks/{service-status-0znmasm1.js → pairing-4b0899hb.js} +2 -2
  13. package/dist/chunks/{service-status-q6jxy1hn.js → pairing-4qjw9nya.js} +15 -38
  14. package/dist/chunks/{service-status-2e16a9cc.js → pairing-5w10ccet.js} +1 -1
  15. package/dist/chunks/{service-status-11d378s5.js → pairing-6xea6nhh.js} +3 -3
  16. package/dist/chunks/{service-status-pf9k0dqe.js → pairing-72ygafj3.js} +2 -2
  17. package/dist/chunks/{service-status-6v4wsps6.js → pairing-7b9xm1qg.js} +3 -2
  18. package/dist/chunks/{service-status-5adf1am9.js → pairing-91mt6ewz.js} +2 -2
  19. package/dist/chunks/pairing-9me4q8wt.js +107 -0
  20. package/dist/chunks/{service-status-6tjqh8g4.js → pairing-a6kxe6a7.js} +3 -3
  21. package/dist/chunks/{service-status-7scj3y0h.js → pairing-aj1jc7g7.js} +8 -8
  22. package/dist/chunks/{service-status-krqg3gd2.js → pairing-cfhthk6z.js} +1 -1
  23. package/dist/chunks/{service-status-xcxwzp6z.js → pairing-e4x9285j.js} +2 -2
  24. package/dist/chunks/{service-status-c2hv5jmf.js → pairing-e7pctymn.js} +1 -1
  25. package/dist/chunks/{service-status-rj8tbp10.js → pairing-f4b2q3tn.js} +1 -1
  26. package/dist/chunks/{service-status-z554rpg5.js → pairing-ga3m49sz.js} +2 -2
  27. package/dist/chunks/{service-status-gymtz25n.js → pairing-gymtz25n.js} +1 -1
  28. package/dist/chunks/{service-status-j4at0y5c.js → pairing-j4at0y5c.js} +1 -1
  29. package/dist/chunks/{service-status-7qrtcnv4.js → pairing-j5aeaa16.js} +1 -1
  30. package/dist/chunks/{service-status-k6dz4enc.js → pairing-k6dz4enc.js} +1 -1
  31. package/dist/chunks/{service-status-crt28xe4.js → pairing-kaqtndqt.js} +2 -2
  32. package/dist/chunks/{service-status-y89d99mz.js → pairing-kcjd09wg.js} +2 -2
  33. package/dist/chunks/{service-status-10kexchg.js → pairing-kd6vzpgq.js} +2 -2
  34. package/dist/chunks/{service-status-vb61dkrm.js → pairing-kqr36gas.js} +8 -8
  35. package/dist/chunks/{service-status-0f489yfb.js → pairing-kyxm98pg.js} +32 -32
  36. package/dist/chunks/{service-status-79n3507d.js → pairing-mte34432.js} +6 -6
  37. package/dist/chunks/{service-status-53jj3zgg.js → pairing-nv8hzzrz.js} +3 -3
  38. package/dist/chunks/{service-status-z9g9xjb3.js → pairing-pmjbkszz.js} +2 -2
  39. package/dist/chunks/pairing-q69f22pd.js +38 -0
  40. package/dist/chunks/{service-status-rkmbbexc.js → pairing-qvy2s3nb.js} +2 -2
  41. package/dist/chunks/{service-status-5ewqf72w.js → pairing-swdgbzpj.js} +2 -2
  42. package/dist/chunks/{service-status-r82dtfrk.js → pairing-t3j5ftv1.js} +3 -3
  43. package/dist/chunks/{service-status-vg0x3zn0.js → pairing-x0608mvx.js} +1 -1
  44. package/dist/chunks/{service-status-5680j7c4.js → pairing-x2dckmx1.js} +15 -17
  45. package/dist/chunks/{service-status-x74w7e1f.js → pairing-x74w7e1f.js} +1 -1
  46. package/dist/chunks/{service-status-a30hykaf.js → pairing-x9vr2ttf.js} +2 -2
  47. package/dist/chunks/{service-status-yzwm8eeq.js → pairing-xmwystkq.js} +2 -2
  48. package/dist/cors.js +1 -1
  49. package/dist/event-feed.js +1 -1
  50. package/dist/fetch.js +49 -50
  51. package/dist/handlers/agent.js +6 -6
  52. package/dist/handlers/command.js +6 -6
  53. package/dist/handlers/config.js +6 -6
  54. package/dist/handlers/credential.js +6 -6
  55. package/dist/handlers/debug.d.ts +2 -1
  56. package/dist/handlers/debug.js +6 -6
  57. package/dist/handlers/event.js +7 -7
  58. package/dist/handlers/form.js +6 -6
  59. package/dist/handlers/fs.js +6 -6
  60. package/dist/handlers/generate.js +6 -6
  61. package/dist/handlers/integration.js +6 -6
  62. package/dist/handlers/location.js +6 -6
  63. package/dist/handlers/mcp.d.ts +3 -1
  64. package/dist/handlers/mcp.js +8 -6
  65. package/dist/handlers/message.js +6 -6
  66. package/dist/handlers/migration.js +6 -6
  67. package/dist/handlers/model.js +6 -6
  68. package/dist/handlers/permission.js +6 -6
  69. package/dist/handlers/persistent-pty.js +8 -8
  70. package/dist/handlers/plugin.js +6 -6
  71. package/dist/handlers/project.js +6 -6
  72. package/dist/handlers/provider.js +6 -6
  73. package/dist/handlers/pty-socket.js +1 -1
  74. package/dist/handlers/pty.d.ts +1 -2
  75. package/dist/handlers/pty.js +8 -9
  76. package/dist/handlers/reference.js +6 -6
  77. package/dist/handlers/rpc.js +6 -6
  78. package/dist/handlers/server.js +9 -9
  79. package/dist/handlers/session-error.js +1 -1
  80. package/dist/handlers/session.js +6 -6
  81. package/dist/handlers/shell.js +6 -6
  82. package/dist/handlers/skill.js +6 -6
  83. package/dist/handlers/vcs.js +6 -6
  84. package/dist/handlers/voice.js +6 -6
  85. package/dist/handlers/websearch.js +6 -6
  86. package/dist/handlers/worktree.js +6 -6
  87. package/dist/handlers.d.ts +1 -1
  88. package/dist/handlers.js +43 -44
  89. package/dist/location.js +2 -2
  90. package/dist/middleware/authorization.js +2 -2
  91. package/dist/middleware/form-location.js +3 -3
  92. package/dist/middleware/schema-error.js +1 -1
  93. package/dist/middleware/session-location.js +3 -3
  94. package/dist/pairing.js +5 -5
  95. package/dist/process.js +53 -53
  96. package/dist/request-tracing.js +1 -1
  97. package/dist/routes.d.ts +3 -3
  98. package/dist/routes.js +46 -47
  99. package/dist/server-info.js +5 -5
  100. package/dist/service-status.js +3 -3
  101. package/dist/workerd.js +50 -51
  102. package/package.json +11 -10
  103. package/dist/chunks/service-status-2f9g7rg2.js +0 -20
  104. package/dist/chunks/service-status-hwdnjend.js +0 -40
  105. package/dist/chunks/service-status-zy1wt1f8.js +0 -23
  106. package/dist/pty-environment.d.ts +0 -13
  107. package/dist/pty-environment.js +0 -12
  108. /package/dist/chunks/{service-status-9rqn6x4v.js → pairing-9rqn6x4v.js} +0 -0
  109. /package/dist/chunks/{service-status-erzfdgke.js → pairing-erzfdgke.js} +0 -0
  110. /package/dist/chunks/{service-status-h6rt5k9s.js → pairing-h6rt5k9s.js} +0 -0
  111. /package/dist/chunks/{service-status-q4bn6dy8.js → pairing-q4bn6dy8.js} +0 -0
  112. /package/dist/chunks/{service-status-smaf4a18.js → pairing-smaf4a18.js} +0 -0
  113. /package/dist/chunks/{service-status-yc7nft6q.js → pairing-yc7nft6q.js} +0 -0
package/dist/api.js CHANGED
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  Api2
3
- } from "./chunks/service-status-r82dtfrk.js";
4
- import"./chunks/service-status-x74w7e1f.js";
5
- import"./chunks/service-status-3154e7fk.js";
6
- import"./chunks/service-status-gymtz25n.js";
7
- import"./chunks/service-status-smaf4a18.js";
3
+ } from "./chunks/pairing-t3j5ftv1.js";
4
+ import"./chunks/pairing-3154e7fk.js";
5
+ import"./chunks/pairing-x74w7e1f.js";
6
+ import"./chunks/pairing-gymtz25n.js";
7
+ import"./chunks/pairing-smaf4a18.js";
8
8
  export {
9
9
  Api2 as Api
10
10
  };
package/dist/auth.js CHANGED
@@ -7,7 +7,7 @@ import {
7
7
  verifySession2,
8
8
  sessionCookieName2,
9
9
  exports_auth
10
- } from "./chunks/service-status-j4at0y5c.js";
10
+ } from "./chunks/pairing-j4at0y5c.js";
11
11
  export {
12
12
  Config2 as Config,
13
13
  SESSION_TTL_SECONDS2 as SESSION_TTL_SECONDS,
@@ -1,15 +1,15 @@
1
1
  import {
2
2
  missingSession2,
3
3
  failedMessageDecode2
4
- } from "./service-status-smaf4a18.js";
4
+ } from "./pairing-smaf4a18.js";
5
5
  import {
6
6
  Api2
7
- } from "./service-status-r82dtfrk.js";
7
+ } from "./pairing-t3j5ftv1.js";
8
8
 
9
9
  // src/handlers/message.ts
10
10
  import { SessionMessage } from "@opencode/core/session/message";
11
11
  import { Session } from "@opencode/core/session";
12
- import { Effect, Schema } from "effect";
12
+ import { Effect, Option, Schema } from "effect";
13
13
  import { HttpApiBuilder } from "effect/http-api";
14
14
  import { InvalidCursorError } from "@opencode/protocol/errors";
15
15
  var DefaultMessagesLimit = 50;
@@ -18,13 +18,13 @@ var Cursor = Schema.Struct({
18
18
  order: Schema.Union([Schema.Literal("asc"), Schema.Literal("desc")]),
19
19
  direction: Schema.Union([Schema.Literal("previous"), Schema.Literal("next")])
20
20
  });
21
- var decodeCursor = Schema.decodeUnknownSync(Cursor);
21
+ var decodeCursor = Schema.decodeUnknownOption(Schema.fromJsonString(Cursor));
22
22
  var cursor = {
23
23
  encode(message, order, direction) {
24
24
  return Buffer.from(JSON.stringify({ id: message.id, order, direction })).toString("base64url");
25
25
  },
26
26
  decode(input) {
27
- return decodeCursor(JSON.parse(Buffer.from(input, "base64url").toString("utf8")));
27
+ return decodeCursor(Buffer.from(input, "base64url").toString("utf8"));
28
28
  }
29
29
  };
30
30
  var MessageHandler2 = HttpApiBuilder.group(Api2, "server.message", (handlers) => Effect.gen(function* () {
@@ -32,10 +32,7 @@ var MessageHandler2 = HttpApiBuilder.group(Api2, "server.message", (handlers) =>
32
32
  return handlers.handle("session.messages", Effect.fn(function* (ctx) {
33
33
  if (ctx.query.cursor && ctx.query.order !== undefined)
34
34
  return yield* new InvalidCursorError({ message: "Cursor cannot be combined with order" });
35
- const decoded = yield* Effect.try({
36
- try: () => ctx.query.cursor ? cursor.decode(ctx.query.cursor) : undefined,
37
- catch: () => new InvalidCursorError({ message: "Invalid cursor" })
38
- });
35
+ const decoded = ctx.query.cursor ? Option.getOrUndefined(cursor.decode(ctx.query.cursor)) ?? (yield* new InvalidCursorError({ message: "Invalid cursor" })) : undefined;
39
36
  const order = decoded?.order ?? ctx.query.order ?? "desc";
40
37
  const messages = yield* session.messages({
41
38
  sessionID: ctx.params.sessionID,
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  Api2
3
- } from "./service-status-r82dtfrk.js";
3
+ } from "./pairing-t3j5ftv1.js";
4
4
 
5
5
  // src/handlers/worktree.ts
6
6
  import { Git } from "@opencode/core/git";
@@ -14,7 +14,7 @@ var WorktreeHandler2 = HttpApiBuilder.group(Api2, "server.worktree", (handlers)
14
14
  return handlers.handle("worktree.list", (ctx) => worktrees.list(ctx.query).pipe(Effect.catchTag("Project.NotFoundError", missingProject))).handle("worktree.create", (ctx) => worktrees.create(ctx.payload).pipe(badRequest)).handle("worktree.remove", (ctx) => worktrees.remove(ctx.payload).pipe(badRequest, Effect.as(HttpApiSchema.NoContent.make()))).handle("worktree.refresh", (ctx) => worktrees.refresh(ctx.payload).pipe(badRequest, Effect.as(HttpApiSchema.NoContent.make())));
15
15
  }));
16
16
  function badRequest(effect) {
17
- return effect.pipe(Effect.catchTag("Project.NotFoundError", missingProject), Effect.mapError((error) => error instanceof ProjectNotFoundError ? error : new WorktreeError({
17
+ return effect.pipe(Effect.mapError((error) => error._tag === "Project.NotFoundError" ? missingProject(error) : new WorktreeError({
18
18
  name: "WorktreeError",
19
19
  data: {
20
20
  message: message(error),
@@ -23,7 +23,7 @@ function badRequest(effect) {
23
23
  })));
24
24
  }
25
25
  function missingProject(error) {
26
- return Effect.fail(new ProjectNotFoundError({ projectID: error.projectID, message: `Project not found: ${error.projectID}` }));
26
+ return new ProjectNotFoundError({ projectID: error.projectID, message: `Project not found: ${error.projectID}` });
27
27
  }
28
28
  function message(error) {
29
29
  if (error instanceof Worktree.SourceDirectoryNotFoundError)
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  response2
3
- } from "./service-status-gymtz25n.js";
3
+ } from "./pairing-gymtz25n.js";
4
4
  import {
5
5
  Api2
6
- } from "./service-status-r82dtfrk.js";
6
+ } from "./pairing-t3j5ftv1.js";
7
7
 
8
8
  // src/handlers/shell.ts
9
9
  import { Shell } from "@opencode/core/shell";
@@ -2,7 +2,7 @@ import {
2
2
  locationErrors2,
3
3
  sessionInfo2,
4
4
  requestRef2
5
- } from "./service-status-gymtz25n.js";
5
+ } from "./pairing-gymtz25n.js";
6
6
 
7
7
  // src/middleware/form-location.ts
8
8
  import { Instance } from "@opencode/core/instance/service";
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  response2
3
- } from "./service-status-gymtz25n.js";
3
+ } from "./pairing-gymtz25n.js";
4
4
  import {
5
5
  Api2
6
- } from "./service-status-r82dtfrk.js";
6
+ } from "./pairing-t3j5ftv1.js";
7
7
 
8
8
  // src/handlers/vcs.ts
9
9
  import { Vcs } from "@opencode/core/vcs";
@@ -1,15 +1,15 @@
1
1
  import {
2
2
  __export
3
- } from "./service-status-9rqn6x4v.js";
3
+ } from "./pairing-9rqn6x4v.js";
4
4
 
5
5
  // src/service-status.ts
6
6
  var exports_service_status = {};
7
7
  __export(exports_service_status, {
8
8
  Status: () => exports_service_status,
9
- make: () => make3
9
+ make: () => make2
10
10
  });
11
11
  import { Effect, Ref } from "effect";
12
- var make3 = Effect.fnUntraced(function* (options = {}) {
12
+ var make2 = Effect.fnUntraced(function* (options = {}) {
13
13
  const current = yield* Ref.make(options.initial ?? { type: "starting" });
14
14
  const beginStopping = Ref.update(current, (status) => status.type === "stopping" ? status : { type: "stopping" });
15
15
  return {
@@ -20,4 +20,4 @@ var make3 = Effect.fnUntraced(function* (options = {}) {
20
20
  };
21
21
  });
22
22
 
23
- export { make3, exports_service_status };
23
+ export { make2, exports_service_status };
@@ -1,22 +1,22 @@
1
1
  import {
2
2
  __export
3
- } from "./service-status-9rqn6x4v.js";
3
+ } from "./pairing-9rqn6x4v.js";
4
4
 
5
5
  // src/server-info.ts
6
6
  var exports_server_info = {};
7
7
  __export(exports_server_info, {
8
8
  ServerInfo: () => exports_server_info,
9
- Service: () => Service5,
9
+ Service: () => Service3,
10
10
  connectionURLs: () => connectionURLs2,
11
- layer: () => layer5
11
+ layer: () => layer3
12
12
  });
13
13
  import { Context, Layer } from "effect";
14
14
  import { networkInterfaces } from "node:os";
15
15
 
16
- class Service5 extends Context.Service()("@opencode/server/ServerInfo") {
16
+ class Service3 extends Context.Service()("@opencode/server/ServerInfo") {
17
17
  }
18
- function layer5(urls, tmp, app = {}) {
19
- return Layer.succeed(Service5, Service5.of({ urls, app, paths: { tmp } }));
18
+ function layer3(urls, tmp, app = {}) {
19
+ return Layer.succeed(Service3, Service3.of({ urls, app, paths: { tmp } }));
20
20
  }
21
21
  function connectionURLs2(value, requestedHostname) {
22
22
  const url = new URL(value);
@@ -38,4 +38,4 @@ function connectionURLs2(value, requestedHostname) {
38
38
  ];
39
39
  }
40
40
 
41
- export { Service5, layer5, connectionURLs2, exports_server_info };
41
+ export { Service3, layer3, connectionURLs2, exports_server_info };
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  response2
3
- } from "./service-status-gymtz25n.js";
3
+ } from "./pairing-gymtz25n.js";
4
4
  import {
5
5
  Api2
6
- } from "./service-status-r82dtfrk.js";
6
+ } from "./pairing-t3j5ftv1.js";
7
7
 
8
8
  // src/handlers/plugin.ts
9
9
  import { Plugin } from "@opencode/core/plugin";
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  response2
3
- } from "./service-status-gymtz25n.js";
3
+ } from "./pairing-gymtz25n.js";
4
4
  import {
5
5
  Api2
6
- } from "./service-status-r82dtfrk.js";
6
+ } from "./pairing-t3j5ftv1.js";
7
7
 
8
8
  // src/handlers/skill.ts
9
9
  import { Skill } from "@opencode/core/skill";
@@ -2,20 +2,17 @@ import {
2
2
  locationErrors2,
3
3
  response2,
4
4
  requestRef2
5
- } from "./service-status-gymtz25n.js";
5
+ } from "./pairing-gymtz25n.js";
6
6
  import {
7
7
  Api2
8
- } from "./service-status-r82dtfrk.js";
8
+ } from "./pairing-t3j5ftv1.js";
9
9
  import {
10
10
  CorsConfig2,
11
11
  isAllowedRequestOrigin2
12
- } from "./service-status-q4bn6dy8.js";
13
- import {
14
- Service2
15
- } from "./service-status-zy1wt1f8.js";
12
+ } from "./pairing-q4bn6dy8.js";
16
13
  import {
17
14
  runPtySocket2
18
- } from "./service-status-h6rt5k9s.js";
15
+ } from "./pairing-h6rt5k9s.js";
19
16
 
20
17
  // src/handlers/pty.ts
21
18
  import { Pty } from "@opencode/core/pty";
@@ -33,63 +30,43 @@ import {
33
30
  PTY_CONNECT_TOKEN_HEADER,
34
31
  PTY_CONNECT_TOKEN_HEADER_VALUE
35
32
  } from "@opencode/protocol/groups/pty";
36
- var ticketScope = Effect.gen(function* () {
37
- const location = yield* Location.Service;
38
- return { directory: location.directory, workspaceID: location.workspaceID };
39
- });
33
+ var notFound = (ptyID) => new PtyNotFoundError({ ptyID, message: `PTY session not found: ${ptyID}` });
40
34
  var PtyHandler2 = HttpApiBuilder.group(Api2, "server.pty", (handlers) => Effect.gen(function* () {
41
35
  const locations = yield* LocationServiceMap.Service;
42
36
  const tickets = yield* PtyTicket.Service;
43
37
  const cors = yield* CorsConfig2;
44
- const environment = yield* Service2;
45
38
  return handlers.handle("pty.list", Effect.fn(function* () {
46
39
  const pty = yield* Pty.Service;
47
40
  return yield* response2(pty.list());
48
41
  })).handle("pty.create", Effect.fn(function* (ctx) {
49
42
  const pty = yield* Pty.Service;
50
43
  const location = yield* Location.Service;
51
- const cwd = ctx.payload.cwd || location.directory;
52
44
  return yield* response2(pty.create({
53
45
  ...ctx.payload,
54
- args: ctx.payload.args ? [...ctx.payload.args] : undefined,
55
- cwd,
56
- env: {
57
- ...ctx.payload.env,
58
- ...yield* environment.get({ directory: location.directory, cwd })
59
- }
46
+ cwd: ctx.payload.cwd || location.directory
60
47
  }));
61
48
  })).handle("pty.get", Effect.fn(function* (ctx) {
62
49
  const pty = yield* Pty.Service;
63
- return yield* response2(pty.get(ctx.params.ptyID).pipe(Effect.catchTag("Pty.NotFoundError", () => new PtyNotFoundError({
64
- ptyID: ctx.params.ptyID,
65
- message: `PTY session not found: ${ctx.params.ptyID}`
66
- }))));
50
+ return yield* response2(pty.get(ctx.params.ptyID).pipe(Effect.catchTag("Pty.NotFoundError", () => notFound(ctx.params.ptyID))));
67
51
  })).handle("pty.update", Effect.fn(function* (ctx) {
68
52
  const pty = yield* Pty.Service;
69
- return yield* response2(pty.update(ctx.params.ptyID, {
70
- ...ctx.payload,
71
- size: ctx.payload.size ? { ...ctx.payload.size } : undefined
72
- }).pipe(Effect.catchTag("Pty.NotFoundError", () => new PtyNotFoundError({
73
- ptyID: ctx.params.ptyID,
74
- message: `PTY session not found: ${ctx.params.ptyID}`
75
- }))));
53
+ return yield* response2(pty.update(ctx.params.ptyID, ctx.payload).pipe(Effect.catchTag("Pty.NotFoundError", () => notFound(ctx.params.ptyID))));
76
54
  })).handle("pty.remove", Effect.fn(function* (ctx) {
77
55
  const pty = yield* Pty.Service;
78
- yield* pty.remove(ctx.params.ptyID).pipe(Effect.catchTag("Pty.NotFoundError", () => new PtyNotFoundError({
79
- ptyID: ctx.params.ptyID,
80
- message: `PTY session not found: ${ctx.params.ptyID}`
81
- })));
56
+ yield* pty.remove(ctx.params.ptyID).pipe(Effect.catchTag("Pty.NotFoundError", () => notFound(ctx.params.ptyID)));
82
57
  return HttpApiSchema.NoContent.make();
83
58
  })).handle("pty.connectToken", Effect.fn(function* (ctx) {
84
59
  const request = yield* HttpServerRequest.HttpServerRequest;
85
60
  if (request.headers[PTY_CONNECT_TOKEN_HEADER] !== PTY_CONNECT_TOKEN_HEADER_VALUE || !isAllowedRequestOrigin2(request.headers.origin, request.headers.host, cors))
86
61
  return yield* new ForbiddenError({ message: "Invalid PTY connect token request" });
87
62
  const pty = yield* Pty.Service;
88
- yield* pty.get(ctx.params.ptyID).pipe(Effect.catchTag("Pty.NotFoundError", () => new PtyNotFoundError({
63
+ const location = yield* Location.Service;
64
+ yield* pty.get(ctx.params.ptyID).pipe(Effect.catchTag("Pty.NotFoundError", () => notFound(ctx.params.ptyID)));
65
+ return yield* response2(tickets.issue({
89
66
  ptyID: ctx.params.ptyID,
90
- message: `PTY session not found: ${ctx.params.ptyID}`
91
- })));
92
- return yield* response2(tickets.issue({ ptyID: ctx.params.ptyID, ...yield* ticketScope }));
67
+ directory: location.directory,
68
+ workspaceID: location.workspaceID
69
+ }));
93
70
  })).handleRaw("pty.connect", Effect.fn("PtyHandler.connect")(function* (ctx) {
94
71
  if (!isAllowedRequestOrigin2(ctx.request.headers.origin, ctx.request.headers.host, cors))
95
72
  return HttpServerResponse.empty({ status: 403 });
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  Api2
3
- } from "./service-status-r82dtfrk.js";
3
+ } from "./pairing-t3j5ftv1.js";
4
4
 
5
5
  // src/handlers/rpc.ts
6
6
  import { Rpc } from "@opencode/core/rpc";
@@ -1,14 +1,14 @@
1
1
  import {
2
2
  missingSession2
3
- } from "./service-status-smaf4a18.js";
3
+ } from "./pairing-smaf4a18.js";
4
4
  import {
5
5
  locationErrors2,
6
6
  response2,
7
7
  sessionInfo2
8
- } from "./service-status-gymtz25n.js";
8
+ } from "./pairing-gymtz25n.js";
9
9
  import {
10
10
  Api2
11
- } from "./service-status-r82dtfrk.js";
11
+ } from "./pairing-t3j5ftv1.js";
12
12
 
13
13
  // src/handlers/permission.ts
14
14
  import { Instance } from "@opencode/core/instance/service";
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  response2
3
- } from "./service-status-gymtz25n.js";
3
+ } from "./pairing-gymtz25n.js";
4
4
  import {
5
5
  Api2
6
- } from "./service-status-r82dtfrk.js";
6
+ } from "./pairing-t3j5ftv1.js";
7
7
 
8
8
  // src/handlers/integration.ts
9
9
  import { Integration } from "@opencode/core/integration";
@@ -4,7 +4,7 @@ import {
4
4
  authorized2,
5
5
  verifySession2,
6
6
  sessionCookieName2
7
- } from "./service-status-j4at0y5c.js";
7
+ } from "./pairing-j4at0y5c.js";
8
8
 
9
9
  // src/middleware/authorization.ts
10
10
  import { UnauthorizedError } from "@opencode/protocol/errors";
@@ -12,6 +12,7 @@ import { Authorization } from "@opencode/protocol/middleware/authorization";
12
12
  import { Authorization as Authorization2 } from "@opencode/protocol/middleware/authorization";
13
13
  import { PTY_CONNECT_PATH, PTY_CONNECT_TICKET_QUERY } from "@opencode/protocol/groups/pty";
14
14
  import { PERSISTENT_PTY_CONNECT_PATH } from "@opencode/protocol/groups/persistent-pty";
15
+ import { MCP_CLIENT_PATH } from "@opencode/protocol/groups/mcp";
15
16
  import { PAIRING_CONNECT_PATH } from "@opencode/protocol/groups/server";
16
17
  import { Effect, Layer, Redacted } from "effect";
17
18
  import { Base64 } from "effect/encoding";
@@ -70,7 +71,7 @@ var authorizationLayer2 = Layer.effect(Authorization, Effect.gen(function* () {
70
71
  const request = yield* HttpServerRequest.HttpServerRequest;
71
72
  const route = yield* HttpRouter.RouteContext;
72
73
  const url = new URL(request.url, "http://localhost");
73
- if ((route.route.path === PTY_CONNECT_PATH || route.route.path === PERSISTENT_PTY_CONNECT_PATH) && !!url.searchParams.get(PTY_CONNECT_TICKET_QUERY) || route.route.path === PAIRING_CONNECT_PATH)
74
+ if ((route.route.path === PTY_CONNECT_PATH || route.route.path === PERSISTENT_PTY_CONNECT_PATH || route.route.path === MCP_CLIENT_PATH) && !!url.searchParams.get(PTY_CONNECT_TICKET_QUERY) || route.route.path === PAIRING_CONNECT_PATH)
74
75
  return yield* effect;
75
76
  if (yield* authorizedRequest2(request, config))
76
77
  return yield* effect;
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  response2
3
- } from "./service-status-gymtz25n.js";
3
+ } from "./pairing-gymtz25n.js";
4
4
  import {
5
5
  Api2
6
- } from "./service-status-r82dtfrk.js";
6
+ } from "./pairing-t3j5ftv1.js";
7
7
 
8
8
  // src/handlers/form.ts
9
9
  import { Form } from "@opencode/core/form";
@@ -0,0 +1,107 @@
1
+ import {
2
+ locationErrors2,
3
+ response2,
4
+ requestRef2
5
+ } from "./pairing-gymtz25n.js";
6
+ import {
7
+ Api2
8
+ } from "./pairing-t3j5ftv1.js";
9
+ import {
10
+ CorsConfig2,
11
+ isAllowedRequestOrigin2
12
+ } from "./pairing-q4bn6dy8.js";
13
+ import {
14
+ runPtySocket2
15
+ } from "./pairing-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,13 +1,13 @@
1
1
  import {
2
2
  Api2
3
- } from "./service-status-r82dtfrk.js";
3
+ } from "./pairing-t3j5ftv1.js";
4
4
  import {
5
5
  CorsConfig2,
6
6
  isAllowedRequestOrigin2
7
- } from "./service-status-q4bn6dy8.js";
7
+ } from "./pairing-q4bn6dy8.js";
8
8
  import {
9
9
  runPtySocket2
10
- } from "./service-status-h6rt5k9s.js";
10
+ } from "./pairing-h6rt5k9s.js";
11
11
 
12
12
  // src/handlers/persistent-pty.ts
13
13
  import { PersistentPty } from "@opencode/core/persistent-pty";
@@ -1,18 +1,18 @@
1
1
  import {
2
2
  Api2
3
- } from "./service-status-r82dtfrk.js";
3
+ } from "./pairing-t3j5ftv1.js";
4
4
  import {
5
5
  SESSION_TTL_SECONDS2,
6
6
  Config2,
7
7
  issueSession2,
8
8
  sessionCookieName2
9
- } from "./service-status-j4at0y5c.js";
10
- import {
11
- Service5
12
- } from "./service-status-x2cwbfak.js";
9
+ } from "./pairing-j4at0y5c.js";
13
10
  import {
14
11
  Service3
15
- } from "./service-status-vb61dkrm.js";
12
+ } from "./pairing-3te71694.js";
13
+ import {
14
+ Service2
15
+ } from "./pairing-kqr36gas.js";
16
16
 
17
17
  // src/handlers/server.ts
18
18
  import { Duration, Effect } from "effect";
@@ -21,10 +21,10 @@ import { HttpApiBuilder } from "effect/http-api";
21
21
  import { PersistentPty } from "@opencode/core/persistent-pty";
22
22
  import { UnauthorizedError } from "@opencode/protocol/errors";
23
23
  var ServerHandler2 = HttpApiBuilder.group(Api2, "server.server", (handlers) => Effect.gen(function* () {
24
- const pairing = yield* Service3;
24
+ const pairing = yield* Service2;
25
25
  const auth = yield* Config2;
26
26
  return handlers.handle("server.info", () => Effect.gen(function* () {
27
- const info = yield* Service5;
27
+ const info = yield* Service3;
28
28
  return {
29
29
  version: info.app.version ?? "unknown",
30
30
  pid: process.pid ?? 0,
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  Api2
3
- } from "./service-status-r82dtfrk.js";
3
+ } from "./pairing-t3j5ftv1.js";
4
4
 
5
5
  // src/handlers/location.ts
6
6
  import { Location } from "@opencode/core/location";
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  awaitPlugins2,
3
3
  response2
4
- } from "./service-status-gymtz25n.js";
4
+ } from "./pairing-gymtz25n.js";
5
5
  import {
6
6
  Api2
7
- } from "./service-status-r82dtfrk.js";
7
+ } from "./pairing-t3j5ftv1.js";
8
8
 
9
9
  // src/handlers/model.ts
10
10
  import { Model } from "@opencode/core/model";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  Api2
3
- } from "./service-status-r82dtfrk.js";
3
+ } from "./pairing-t3j5ftv1.js";
4
4
 
5
5
  // src/handlers/config.ts
6
6
  import { Config } from "@opencode/core/config";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  Api2
3
- } from "./service-status-r82dtfrk.js";
3
+ } from "./pairing-t3j5ftv1.js";
4
4
 
5
5
  // src/handlers/credential.ts
6
6
  import { Credential } from "@opencode/core/credential";
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  response2
3
- } from "./service-status-gymtz25n.js";
3
+ } from "./pairing-gymtz25n.js";
4
4
  import {
5
5
  Api2
6
- } from "./service-status-r82dtfrk.js";
6
+ } from "./pairing-t3j5ftv1.js";
7
7
 
8
8
  // src/handlers/agent.ts
9
9
  import { Agent } from "@opencode/core/agent";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  missingSession2
3
- } from "./service-status-smaf4a18.js";
3
+ } from "./pairing-smaf4a18.js";
4
4
 
5
5
  // src/location.ts
6
6
  import { FileSystem } from "@opencode/core/filesystem";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  __export
3
- } from "./service-status-9rqn6x4v.js";
3
+ } from "./pairing-9rqn6x4v.js";
4
4
 
5
5
  // src/auth.ts
6
6
  var exports_auth = {};