@opencode/server 0.0.0-dev-19795 → 0.0.0-dev-19812
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api.js +10 -9
- package/dist/auth.js +12 -17
- package/dist/chunks/process-172x6jgf.js +139 -0
- package/dist/chunks/process-18k6g42r.js +36 -0
- package/dist/chunks/process-1crq7hen.js +13 -0
- package/dist/chunks/process-27edjygf.js +33 -0
- package/dist/chunks/process-3esm6t0a.js +156 -0
- package/dist/chunks/process-3ra48t04.js +26 -0
- package/dist/chunks/process-8j6eh3dh.js +55 -0
- package/dist/chunks/process-910kejdj.js +37 -0
- package/dist/chunks/process-9rqn6x4v.js +16 -0
- package/dist/chunks/process-b0dj656z.js +13 -0
- package/dist/chunks/process-b4s3wxap.js +23 -0
- package/dist/chunks/process-c23ng5tp.js +17 -0
- package/dist/chunks/process-d0efjmp3.js +83 -0
- package/dist/chunks/process-d5nhwenp.js +22 -0
- package/dist/chunks/process-dhcrxjg3.js +163 -0
- package/dist/chunks/process-fa3dg36p.js +15 -0
- package/dist/chunks/process-gw2hwgqh.js +20 -0
- package/dist/chunks/process-h965rd83.js +25 -0
- package/dist/chunks/process-hezj1jdf.js +7 -0
- package/dist/chunks/process-j26nh0zz.js +40 -0
- package/dist/chunks/process-ja6yvede.js +22 -0
- package/dist/chunks/process-k319q0y1.js +39 -0
- package/dist/chunks/process-k8tgqrb7.js +61 -0
- package/dist/chunks/process-kadtbwy3.js +77 -0
- package/dist/chunks/process-kb9735wh.js +26 -0
- package/dist/chunks/process-kgbwhj3q.js +149 -0
- package/dist/chunks/process-kheky2r0.js +35 -0
- package/dist/chunks/process-knez9aqv.js +13 -0
- package/dist/chunks/process-ks9pc2xc.js +19 -0
- package/dist/chunks/process-m5dqr0xs.js +21 -0
- package/dist/chunks/process-m6wvgbfq.js +60 -0
- package/dist/chunks/process-m8y6333k.js +346 -0
- package/dist/chunks/process-mx2h5aqn.js +59 -0
- package/dist/chunks/process-prrj1pgd.js +42 -0
- package/dist/chunks/process-q4bn6dy8.js +39 -0
- package/dist/chunks/process-qc2xtz00.js +34 -0
- package/dist/chunks/process-qswqf30g.js +25 -0
- package/dist/chunks/process-rkdaz036.js +32 -0
- package/dist/chunks/process-smaf4a18.js +28 -0
- package/dist/chunks/process-t7k3q1ah.js +23 -0
- package/dist/chunks/process-t8yzmczr.js +18 -0
- package/dist/chunks/process-tp6dn9dc.js +99 -0
- package/dist/chunks/process-w0mvbrhx.js +22 -0
- package/dist/chunks/process-wt4btb09.js +13 -0
- package/dist/chunks/process-xettb16v.js +22 -0
- package/dist/chunks/process-xn1y01ws.js +29 -0
- package/dist/chunks/process-xsrtpxyd.js +23 -0
- package/dist/chunks/process-yc7nft6q.js +5 -0
- package/dist/chunks/process-zyv89x5n.js +30 -0
- package/dist/cors.js +10 -36
- package/dist/event-feed.js +20 -60
- package/dist/fetch.js +53 -11
- package/dist/handlers/agent.js +11 -17
- package/dist/handlers/command.js +11 -5
- package/dist/handlers/config.js +11 -16
- package/dist/handlers/credential.js +11 -14
- package/dist/handlers/debug.js +11 -11
- package/dist/handlers/event.js +12 -27
- package/dist/handlers/form.js +11 -9
- package/dist/handlers/fs.js +11 -22
- package/dist/handlers/generate.js +11 -15
- package/dist/handlers/integration.js +10 -142
- package/dist/handlers/location.js +11 -16
- package/dist/handlers/mcp.js +11 -31
- package/dist/handlers/message.js +10 -42
- package/dist/handlers/migration.js +11 -7
- package/dist/handlers/model.js +11 -14
- package/dist/handlers/permission.js +11 -57
- package/dist/handlers/persistent-pty.js +12 -135
- package/dist/handlers/plugin.js +11 -47
- package/dist/handlers/project.js +11 -9
- package/dist/handlers/provider.js +11 -20
- package/dist/handlers/pty-socket.js +6 -4
- package/dist/handlers/pty.js +13 -107
- package/dist/handlers/reference.js +11 -5
- package/dist/handlers/rpc.js +11 -15
- package/dist/handlers/server.js +12 -13
- package/dist/handlers/session-error.js +12 -26
- package/dist/handlers/session.js +10 -311
- package/dist/handlers/shell.js +11 -25
- package/dist/handlers/skill.js +11 -5
- package/dist/handlers/vcs.js +11 -19
- package/dist/handlers/websearch.js +11 -31
- package/dist/handlers/worktree.js +11 -37
- package/dist/handlers.js +46 -33
- package/dist/location.js +15 -49
- package/dist/middleware/authorization.js +11 -49
- package/dist/middleware/form-location.js +10 -25
- package/dist/middleware/schema-error.js +8 -15
- package/dist/middleware/session-location.js +10 -19
- package/dist/options.js +5 -1
- package/dist/process.js +108 -28
- package/dist/pty-environment.js +12 -9
- package/dist/request-tracing.js +6 -2
- package/dist/routes.js +52 -118
- package/dist/server-info.js +12 -22
- package/dist/service-status.js +8 -11
- package/dist/workerd.js +80 -12
- package/package.json +8 -8
package/dist/api.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
import
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
1
|
+
import {
|
|
2
|
+
Api2
|
|
3
|
+
} from "./chunks/process-ks9pc2xc.js";
|
|
4
|
+
import"./chunks/process-kb9735wh.js";
|
|
5
|
+
import"./chunks/process-27edjygf.js";
|
|
6
|
+
import"./chunks/process-8j6eh3dh.js";
|
|
7
|
+
import"./chunks/process-smaf4a18.js";
|
|
8
|
+
export {
|
|
9
|
+
Api2 as Api
|
|
10
|
+
};
|
package/dist/auth.js
CHANGED
|
@@ -1,17 +1,12 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
return Option.isSome(config.password) && config.password.value !== "";
|
|
14
|
-
}
|
|
15
|
-
export function authorized(credentials, config) {
|
|
16
|
-
return Option.isSome(config.password) && credentials.username === config.username && Redacted.value(credentials.password) === config.password.value;
|
|
17
|
-
}
|
|
1
|
+
import {
|
|
2
|
+
Config2,
|
|
3
|
+
required2,
|
|
4
|
+
authorized2,
|
|
5
|
+
exports_auth
|
|
6
|
+
} from "./chunks/process-zyv89x5n.js";
|
|
7
|
+
export {
|
|
8
|
+
Config2 as Config,
|
|
9
|
+
exports_auth as ServerAuth,
|
|
10
|
+
authorized2 as authorized,
|
|
11
|
+
required2 as required
|
|
12
|
+
};
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import {
|
|
2
|
+
response2
|
|
3
|
+
} from "./process-8j6eh3dh.js";
|
|
4
|
+
import {
|
|
5
|
+
Api2
|
|
6
|
+
} from "./process-ks9pc2xc.js";
|
|
7
|
+
import {
|
|
8
|
+
CorsConfig2,
|
|
9
|
+
isAllowedRequestOrigin2
|
|
10
|
+
} from "./process-q4bn6dy8.js";
|
|
11
|
+
import {
|
|
12
|
+
Service2
|
|
13
|
+
} from "./process-t7k3q1ah.js";
|
|
14
|
+
import {
|
|
15
|
+
runPtySocket2
|
|
16
|
+
} from "./process-hezj1jdf.js";
|
|
17
|
+
|
|
18
|
+
// src/handlers/pty.ts
|
|
19
|
+
import { Pty } from "@opencode/core/pty";
|
|
20
|
+
import { PtyProtocol } from "@opencode/core/pty/protocol";
|
|
21
|
+
import { PtyTicket } from "@opencode/core/pty/ticket";
|
|
22
|
+
import { Location } from "@opencode/core/location";
|
|
23
|
+
import { Effect, Queue } from "effect";
|
|
24
|
+
import { HttpServerRequest, HttpServerResponse } from "effect/unstable/http";
|
|
25
|
+
import { HttpApiBuilder, HttpApiSchema } from "effect/unstable/httpapi";
|
|
26
|
+
import { Socket } from "effect/unstable/socket";
|
|
27
|
+
import { ForbiddenError, PtyNotFoundError } from "@opencode/protocol/errors";
|
|
28
|
+
import {
|
|
29
|
+
PTY_CONNECT_TICKET_QUERY,
|
|
30
|
+
PTY_CONNECT_TOKEN_HEADER,
|
|
31
|
+
PTY_CONNECT_TOKEN_HEADER_VALUE
|
|
32
|
+
} from "@opencode/protocol/groups/pty";
|
|
33
|
+
var ticketScope = Effect.gen(function* () {
|
|
34
|
+
const location = yield* Location.Service;
|
|
35
|
+
return { directory: location.directory, workspaceID: location.workspaceID };
|
|
36
|
+
});
|
|
37
|
+
var PtyHandler2 = HttpApiBuilder.group(Api2, "server.pty", (handlers) => Effect.gen(function* () {
|
|
38
|
+
const tickets = yield* PtyTicket.Service;
|
|
39
|
+
const cors = yield* CorsConfig2;
|
|
40
|
+
const environment = yield* Service2;
|
|
41
|
+
return handlers.handle("pty.list", Effect.fn(function* () {
|
|
42
|
+
const pty = yield* Pty.Service;
|
|
43
|
+
return yield* response2(pty.list());
|
|
44
|
+
})).handle("pty.create", Effect.fn(function* (ctx) {
|
|
45
|
+
const pty = yield* Pty.Service;
|
|
46
|
+
const location = yield* Location.Service;
|
|
47
|
+
const cwd = ctx.payload.cwd || location.directory;
|
|
48
|
+
return yield* response2(pty.create({
|
|
49
|
+
...ctx.payload,
|
|
50
|
+
args: ctx.payload.args ? [...ctx.payload.args] : undefined,
|
|
51
|
+
cwd,
|
|
52
|
+
env: {
|
|
53
|
+
...ctx.payload.env,
|
|
54
|
+
...yield* environment.get({ directory: location.directory, cwd })
|
|
55
|
+
}
|
|
56
|
+
}));
|
|
57
|
+
})).handle("pty.get", Effect.fn(function* (ctx) {
|
|
58
|
+
const pty = yield* Pty.Service;
|
|
59
|
+
return yield* response2(pty.get(ctx.params.ptyID).pipe(Effect.catchTag("Pty.NotFoundError", () => new PtyNotFoundError({
|
|
60
|
+
ptyID: ctx.params.ptyID,
|
|
61
|
+
message: `PTY session not found: ${ctx.params.ptyID}`
|
|
62
|
+
}))));
|
|
63
|
+
})).handle("pty.update", Effect.fn(function* (ctx) {
|
|
64
|
+
const pty = yield* Pty.Service;
|
|
65
|
+
return yield* response2(pty.update(ctx.params.ptyID, {
|
|
66
|
+
...ctx.payload,
|
|
67
|
+
size: ctx.payload.size ? { ...ctx.payload.size } : undefined
|
|
68
|
+
}).pipe(Effect.catchTag("Pty.NotFoundError", () => new PtyNotFoundError({
|
|
69
|
+
ptyID: ctx.params.ptyID,
|
|
70
|
+
message: `PTY session not found: ${ctx.params.ptyID}`
|
|
71
|
+
}))));
|
|
72
|
+
})).handle("pty.remove", Effect.fn(function* (ctx) {
|
|
73
|
+
const pty = yield* Pty.Service;
|
|
74
|
+
yield* pty.remove(ctx.params.ptyID).pipe(Effect.catchTag("Pty.NotFoundError", () => new PtyNotFoundError({
|
|
75
|
+
ptyID: ctx.params.ptyID,
|
|
76
|
+
message: `PTY session not found: ${ctx.params.ptyID}`
|
|
77
|
+
})));
|
|
78
|
+
return HttpApiSchema.NoContent.make();
|
|
79
|
+
})).handle("pty.connectToken", Effect.fn(function* (ctx) {
|
|
80
|
+
const request = yield* HttpServerRequest.HttpServerRequest;
|
|
81
|
+
if (request.headers[PTY_CONNECT_TOKEN_HEADER] !== PTY_CONNECT_TOKEN_HEADER_VALUE || !isAllowedRequestOrigin2(request.headers.origin, request.headers.host, cors))
|
|
82
|
+
return yield* new ForbiddenError({ message: "Invalid PTY connect token request" });
|
|
83
|
+
const pty = yield* Pty.Service;
|
|
84
|
+
yield* pty.get(ctx.params.ptyID).pipe(Effect.catchTag("Pty.NotFoundError", () => new PtyNotFoundError({
|
|
85
|
+
ptyID: ctx.params.ptyID,
|
|
86
|
+
message: `PTY session not found: ${ctx.params.ptyID}`
|
|
87
|
+
})));
|
|
88
|
+
return yield* response2(tickets.issue({ ptyID: ctx.params.ptyID, ...yield* ticketScope }));
|
|
89
|
+
})).handleRaw("pty.connect", Effect.fn("PtyHandler.connect")(function* (ctx) {
|
|
90
|
+
const pty = yield* Pty.Service;
|
|
91
|
+
const exists = yield* pty.get(ctx.params.ptyID).pipe(Effect.as(true), Effect.catchTag("Pty.NotFoundError", () => Effect.succeed(false)));
|
|
92
|
+
if (!exists)
|
|
93
|
+
return HttpServerResponse.empty({ status: 404 });
|
|
94
|
+
const url = new URL(ctx.request.url, "http://localhost");
|
|
95
|
+
const ticket = url.searchParams.get(PTY_CONNECT_TICKET_QUERY);
|
|
96
|
+
if (ticket) {
|
|
97
|
+
const valid = isAllowedRequestOrigin2(ctx.request.headers.origin, ctx.request.headers.host, cors) ? yield* tickets.consume({ ticket, ptyID: ctx.params.ptyID, ...yield* ticketScope }) : false;
|
|
98
|
+
if (!valid)
|
|
99
|
+
return HttpServerResponse.empty({ status: 403 });
|
|
100
|
+
}
|
|
101
|
+
const parsedCursor = url.searchParams.get("cursor");
|
|
102
|
+
const cursorNumber = parsedCursor === null ? undefined : Number(parsedCursor);
|
|
103
|
+
const cursor = cursorNumber !== undefined && Number.isSafeInteger(cursorNumber) && cursorNumber >= -1 ? cursorNumber : undefined;
|
|
104
|
+
const socket = yield* Effect.orDie(ctx.request.upgrade);
|
|
105
|
+
const write = yield* socket.writer;
|
|
106
|
+
const closeAccepted = (event) => socket.runRaw(() => Effect.void, { onOpen: write(event).pipe(Effect.catch(() => Effect.void)) }).pipe(Effect.timeout("1 second"), Effect.catchReason("SocketError", "SocketCloseError", () => Effect.void), Effect.catch(() => Effect.void));
|
|
107
|
+
const outbox = yield* Queue.unbounded();
|
|
108
|
+
const attachment = yield* pty.attach(ctx.params.ptyID, {
|
|
109
|
+
cursor,
|
|
110
|
+
onData: (chunk) => Queue.offerUnsafe(outbox, chunk),
|
|
111
|
+
onEnd: () => Queue.offerUnsafe(outbox, new Socket.CloseEvent(1000))
|
|
112
|
+
}).pipe(Effect.catchTags({
|
|
113
|
+
"Pty.NotFoundError": () => closeAccepted(new Socket.CloseEvent(4404, "session not found")).pipe(Effect.as(undefined)),
|
|
114
|
+
"Pty.ExitedError": () => closeAccepted(new Socket.CloseEvent(4404, "session exited")).pipe(Effect.as(undefined))
|
|
115
|
+
}));
|
|
116
|
+
if (!attachment)
|
|
117
|
+
return HttpServerResponse.empty();
|
|
118
|
+
for (const chunk of PtyProtocol.chunks(attachment.replay))
|
|
119
|
+
Queue.offerUnsafe(outbox, chunk);
|
|
120
|
+
Queue.offerUnsafe(outbox, PtyProtocol.metaFrame(attachment.cursor));
|
|
121
|
+
attachment.activate();
|
|
122
|
+
const drain = Effect.gen(function* () {
|
|
123
|
+
while (true) {
|
|
124
|
+
const item = yield* Queue.take(outbox);
|
|
125
|
+
yield* write(item);
|
|
126
|
+
if (item instanceof Socket.CloseEvent)
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
});
|
|
130
|
+
yield* runPtySocket2(drain, socket.runRaw((message) => {
|
|
131
|
+
const decoded = PtyProtocol.decodeInput(message);
|
|
132
|
+
if (decoded !== undefined)
|
|
133
|
+
attachment.write(decoded);
|
|
134
|
+
}), attachment.detach).pipe(Effect.catchReason("SocketError", "SocketCloseError", () => Effect.void), Effect.orDie);
|
|
135
|
+
return HttpServerResponse.empty();
|
|
136
|
+
}));
|
|
137
|
+
}));
|
|
138
|
+
|
|
139
|
+
export { PtyHandler2 };
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import {
|
|
2
|
+
__export
|
|
3
|
+
} from "./process-9rqn6x4v.js";
|
|
4
|
+
|
|
5
|
+
// src/server-info.ts
|
|
6
|
+
var exports_server_info = {};
|
|
7
|
+
__export(exports_server_info, {
|
|
8
|
+
ServerInfo: () => exports_server_info,
|
|
9
|
+
Service: () => Service4,
|
|
10
|
+
connectionURLs: () => connectionURLs2,
|
|
11
|
+
layer: () => layer5
|
|
12
|
+
});
|
|
13
|
+
import { Context, Layer } from "effect";
|
|
14
|
+
import { networkInterfaces } from "node:os";
|
|
15
|
+
|
|
16
|
+
class Service4 extends Context.Service()("@opencode/server/ServerInfo") {
|
|
17
|
+
}
|
|
18
|
+
function layer5(urls, tmp, app = {}) {
|
|
19
|
+
return Layer.succeed(Service4, Service4.of({ urls, app, paths: { tmp } }));
|
|
20
|
+
}
|
|
21
|
+
function connectionURLs2(value, requestedHostname) {
|
|
22
|
+
const url = new URL(value);
|
|
23
|
+
const hostname = requestedHostname ?? url.hostname;
|
|
24
|
+
const family = hostname === "0.0.0.0" ? "IPv4" : hostname === "::" || hostname === "[::]" ? "IPv6" : undefined;
|
|
25
|
+
if (family === undefined)
|
|
26
|
+
return [value];
|
|
27
|
+
return [
|
|
28
|
+
...new Set(Object.values(networkInterfaces()).flatMap((entries) => entries ?? []).filter((entry) => !entry.internal && entry.family === family).map((entry) => {
|
|
29
|
+
const result = new URL(value);
|
|
30
|
+
result.hostname = family === "IPv6" ? `[${entry.address}]` : entry.address;
|
|
31
|
+
return result.toString().replace(/\/$/, "");
|
|
32
|
+
}))
|
|
33
|
+
];
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export { Service4, layer5, connectionURLs2, exports_server_info };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import {
|
|
2
|
+
response2
|
|
3
|
+
} from "./process-8j6eh3dh.js";
|
|
4
|
+
import {
|
|
5
|
+
Api2
|
|
6
|
+
} from "./process-ks9pc2xc.js";
|
|
7
|
+
|
|
8
|
+
// src/handlers/command.ts
|
|
9
|
+
import { Command } from "@opencode/core/command";
|
|
10
|
+
import { HttpApiBuilder } from "effect/unstable/httpapi";
|
|
11
|
+
var CommandHandler2 = HttpApiBuilder.group(Api2, "server.command", (handlers) => handlers.handle("command.list", () => response2(Command.Service.use((command) => command.list()))));
|
|
12
|
+
|
|
13
|
+
export { CommandHandler2 };
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import {
|
|
2
|
+
sessionInfo2,
|
|
3
|
+
requestRef2
|
|
4
|
+
} from "./process-8j6eh3dh.js";
|
|
5
|
+
|
|
6
|
+
// src/middleware/form-location.ts
|
|
7
|
+
import { Instance } from "@opencode/core/instance/service";
|
|
8
|
+
import { LocationServiceMap } from "@opencode/core/location-services";
|
|
9
|
+
import { Session } from "@opencode/core/session";
|
|
10
|
+
import { InvalidRequestError, SessionNotFoundError } from "@opencode/protocol/errors";
|
|
11
|
+
import { Effect, Layer } from "effect";
|
|
12
|
+
import { HttpRouter, HttpServerRequest } from "effect/unstable/http";
|
|
13
|
+
import { HttpApiMiddleware } from "effect/unstable/httpapi";
|
|
14
|
+
class FormLocationMiddleware2 extends HttpApiMiddleware.Service()("@opencode/HttpApiFormLocation", {
|
|
15
|
+
error: [InvalidRequestError, SessionNotFoundError]
|
|
16
|
+
}) {
|
|
17
|
+
}
|
|
18
|
+
var formLocationLayer2 = Layer.effect(FormLocationMiddleware2, Effect.gen(function* () {
|
|
19
|
+
const sessions = yield* Session.Service;
|
|
20
|
+
const instances = yield* Instance.Service;
|
|
21
|
+
const locations = yield* LocationServiceMap.Service;
|
|
22
|
+
return FormLocationMiddleware2.of((effect) => Effect.gen(function* () {
|
|
23
|
+
const route = yield* HttpRouter.RouteContext;
|
|
24
|
+
if (route.params.sessionID === "global") {
|
|
25
|
+
const request = yield* HttpServerRequest.HttpServerRequest;
|
|
26
|
+
return yield* effect.pipe(Effect.provide(locations.get(requestRef2(request))));
|
|
27
|
+
}
|
|
28
|
+
const session = yield* sessionInfo2(sessions, route.params.sessionID);
|
|
29
|
+
return yield* effect.pipe(instances.provide(session));
|
|
30
|
+
}));
|
|
31
|
+
}));
|
|
32
|
+
|
|
33
|
+
export { FormLocationMiddleware2, formLocationLayer2 };
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
import {
|
|
2
|
+
response2
|
|
3
|
+
} from "./process-8j6eh3dh.js";
|
|
4
|
+
import {
|
|
5
|
+
Api2
|
|
6
|
+
} from "./process-ks9pc2xc.js";
|
|
7
|
+
|
|
8
|
+
// src/handlers/integration.ts
|
|
9
|
+
import { Integration } from "@opencode/core/integration";
|
|
10
|
+
import { Plugin } from "@opencode/core/plugin";
|
|
11
|
+
import { Effect } from "effect";
|
|
12
|
+
import { HttpApiBuilder, HttpApiSchema } from "effect/unstable/httpapi";
|
|
13
|
+
import {
|
|
14
|
+
IntegrationAttemptNotFoundError,
|
|
15
|
+
IntegrationMethodNotFoundError,
|
|
16
|
+
IntegrationNotFoundError,
|
|
17
|
+
InvalidRequestError
|
|
18
|
+
} from "@opencode/protocol/errors";
|
|
19
|
+
import { WellKnown } from "@opencode/core/wellknown";
|
|
20
|
+
var authorize = (effect) => effect.pipe(Effect.mapError((error) => new InvalidRequestError({
|
|
21
|
+
message: error.cause instanceof Error && error.cause.message.trim() ? error.cause.message : "Authentication failed",
|
|
22
|
+
kind: "integration_authorization"
|
|
23
|
+
})));
|
|
24
|
+
var IntegrationHandler2 = HttpApiBuilder.group(Api2, "server.integration", (handlers) => Effect.gen(function* () {
|
|
25
|
+
return handlers.handle("integration.list", Effect.fn(function* () {
|
|
26
|
+
yield* Plugin.awaitActivation;
|
|
27
|
+
const service = yield* Integration.Service;
|
|
28
|
+
return yield* response2(service.list());
|
|
29
|
+
})).handle("integration.get", Effect.fn(function* (ctx) {
|
|
30
|
+
const service = yield* Integration.Service;
|
|
31
|
+
const integration = yield* service.get(ctx.params.integrationID);
|
|
32
|
+
if (!integration)
|
|
33
|
+
return yield* new IntegrationNotFoundError({
|
|
34
|
+
integrationID: ctx.params.integrationID,
|
|
35
|
+
message: `Integration not found: ${ctx.params.integrationID}`
|
|
36
|
+
});
|
|
37
|
+
return yield* response2(Effect.succeed(integration));
|
|
38
|
+
})).handle("integration.wellknown.add", Effect.fn(function* (ctx) {
|
|
39
|
+
const wellknown = yield* WellKnown.Service;
|
|
40
|
+
const integration = yield* Integration.Service;
|
|
41
|
+
yield* wellknown.add(ctx.payload.url).pipe(Effect.mapError((error) => new InvalidRequestError({ message: error.message, kind: "well_known_discovery" })));
|
|
42
|
+
yield* integration.reload();
|
|
43
|
+
return HttpApiSchema.NoContent.make();
|
|
44
|
+
})).handle("integration.connect.key", Effect.fn(function* (ctx) {
|
|
45
|
+
const service = yield* Integration.Service;
|
|
46
|
+
if (!(yield* service.get(ctx.params.integrationID)))
|
|
47
|
+
return yield* new IntegrationNotFoundError({
|
|
48
|
+
integrationID: ctx.params.integrationID,
|
|
49
|
+
message: `Integration not found: ${ctx.params.integrationID}`
|
|
50
|
+
});
|
|
51
|
+
yield* authorize(service.connection.key({
|
|
52
|
+
integrationID: ctx.params.integrationID,
|
|
53
|
+
key: ctx.payload.key,
|
|
54
|
+
answer: ctx.payload.answer,
|
|
55
|
+
label: ctx.payload.label
|
|
56
|
+
}));
|
|
57
|
+
return HttpApiSchema.NoContent.make();
|
|
58
|
+
})).handle("integration.oauth.connect", Effect.fn(function* (ctx) {
|
|
59
|
+
const service = yield* Integration.Service;
|
|
60
|
+
return yield* response2(authorize(service.oauth.connect({
|
|
61
|
+
integrationID: ctx.params.integrationID,
|
|
62
|
+
methodID: ctx.payload.methodID,
|
|
63
|
+
answer: ctx.payload.answer,
|
|
64
|
+
label: ctx.payload.label
|
|
65
|
+
})));
|
|
66
|
+
})).handle("integration.oauth.status", Effect.fn(function* (ctx) {
|
|
67
|
+
const service = yield* Integration.Service;
|
|
68
|
+
if (!(yield* service.get(ctx.params.integrationID)))
|
|
69
|
+
return yield* new IntegrationNotFoundError({
|
|
70
|
+
integrationID: ctx.params.integrationID,
|
|
71
|
+
message: `Integration not found: ${ctx.params.integrationID}`
|
|
72
|
+
});
|
|
73
|
+
return yield* response2(service.oauth.status({
|
|
74
|
+
integrationID: ctx.params.integrationID,
|
|
75
|
+
attemptID: ctx.params.attemptID
|
|
76
|
+
}).pipe(Effect.mapError((error) => new IntegrationAttemptNotFoundError({
|
|
77
|
+
integrationID: error.integrationID,
|
|
78
|
+
attemptID: error.attemptID,
|
|
79
|
+
message: `OAuth attempt not found: ${error.attemptID}`
|
|
80
|
+
}))));
|
|
81
|
+
})).handle("integration.oauth.complete", Effect.fn(function* (ctx) {
|
|
82
|
+
const service = yield* Integration.Service;
|
|
83
|
+
if (!(yield* service.get(ctx.params.integrationID)))
|
|
84
|
+
return yield* new IntegrationNotFoundError({
|
|
85
|
+
integrationID: ctx.params.integrationID,
|
|
86
|
+
message: `Integration not found: ${ctx.params.integrationID}`
|
|
87
|
+
});
|
|
88
|
+
yield* service.oauth.complete({
|
|
89
|
+
integrationID: ctx.params.integrationID,
|
|
90
|
+
attemptID: ctx.params.attemptID,
|
|
91
|
+
code: ctx.payload.code
|
|
92
|
+
}).pipe(Effect.mapError((error) => {
|
|
93
|
+
if (error._tag === "Integration.AttemptNotFound")
|
|
94
|
+
return new IntegrationAttemptNotFoundError({
|
|
95
|
+
integrationID: error.integrationID,
|
|
96
|
+
attemptID: error.attemptID,
|
|
97
|
+
message: `OAuth attempt not found: ${error.attemptID}`
|
|
98
|
+
});
|
|
99
|
+
return new InvalidRequestError({
|
|
100
|
+
message: error._tag === "Integration.CodeRequired" ? "Authorization code is required" : "Authentication failed",
|
|
101
|
+
kind: error._tag === "Integration.CodeRequired" ? "integration_code_required" : "integration_authorization"
|
|
102
|
+
});
|
|
103
|
+
}));
|
|
104
|
+
return HttpApiSchema.NoContent.make();
|
|
105
|
+
})).handle("integration.oauth.cancel", Effect.fn(function* (ctx) {
|
|
106
|
+
const service = yield* Integration.Service;
|
|
107
|
+
yield* service.oauth.cancel({
|
|
108
|
+
integrationID: ctx.params.integrationID,
|
|
109
|
+
attemptID: ctx.params.attemptID
|
|
110
|
+
});
|
|
111
|
+
return HttpApiSchema.NoContent.make();
|
|
112
|
+
})).handle("integration.command.connect", Effect.fn(function* (ctx) {
|
|
113
|
+
const service = yield* Integration.Service;
|
|
114
|
+
const integration = yield* service.get(ctx.params.integrationID);
|
|
115
|
+
if (!integration)
|
|
116
|
+
return yield* new IntegrationNotFoundError({
|
|
117
|
+
integrationID: ctx.params.integrationID,
|
|
118
|
+
message: `Integration not found: ${ctx.params.integrationID}`
|
|
119
|
+
});
|
|
120
|
+
if (!integration.methods.some((method) => method.type === "command" && method.id === ctx.payload.methodID))
|
|
121
|
+
return yield* new IntegrationMethodNotFoundError({
|
|
122
|
+
integrationID: ctx.params.integrationID,
|
|
123
|
+
methodID: ctx.payload.methodID,
|
|
124
|
+
message: `Integration method not found: ${ctx.payload.methodID}`
|
|
125
|
+
});
|
|
126
|
+
return yield* response2(authorize(service.command.connect({
|
|
127
|
+
integrationID: ctx.params.integrationID,
|
|
128
|
+
methodID: ctx.payload.methodID,
|
|
129
|
+
label: ctx.payload.label
|
|
130
|
+
})));
|
|
131
|
+
})).handle("integration.command.status", Effect.fn(function* (ctx) {
|
|
132
|
+
const service = yield* Integration.Service;
|
|
133
|
+
if (!(yield* service.get(ctx.params.integrationID)))
|
|
134
|
+
return yield* new IntegrationNotFoundError({
|
|
135
|
+
integrationID: ctx.params.integrationID,
|
|
136
|
+
message: `Integration not found: ${ctx.params.integrationID}`
|
|
137
|
+
});
|
|
138
|
+
return yield* response2(service.command.status({
|
|
139
|
+
integrationID: ctx.params.integrationID,
|
|
140
|
+
attemptID: ctx.params.attemptID
|
|
141
|
+
}).pipe(Effect.mapError((error) => new IntegrationAttemptNotFoundError({
|
|
142
|
+
integrationID: error.integrationID,
|
|
143
|
+
attemptID: error.attemptID,
|
|
144
|
+
message: `Command attempt not found: ${error.attemptID}`
|
|
145
|
+
}))));
|
|
146
|
+
})).handle("integration.command.cancel", Effect.fn(function* (ctx) {
|
|
147
|
+
const service = yield* Integration.Service;
|
|
148
|
+
yield* service.command.cancel({
|
|
149
|
+
integrationID: ctx.params.integrationID,
|
|
150
|
+
attemptID: ctx.params.attemptID
|
|
151
|
+
});
|
|
152
|
+
return HttpApiSchema.NoContent.make();
|
|
153
|
+
}));
|
|
154
|
+
}));
|
|
155
|
+
|
|
156
|
+
export { IntegrationHandler2 };
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import {
|
|
2
|
+
isAllowedCorsOrigin2
|
|
3
|
+
} from "./process-q4bn6dy8.js";
|
|
4
|
+
import {
|
|
5
|
+
createRoutes2
|
|
6
|
+
} from "./process-kgbwhj3q.js";
|
|
7
|
+
import {
|
|
8
|
+
__export
|
|
9
|
+
} from "./process-9rqn6x4v.js";
|
|
10
|
+
|
|
11
|
+
// src/fetch.ts
|
|
12
|
+
var exports_fetch = {};
|
|
13
|
+
__export(exports_fetch, {
|
|
14
|
+
ServerFetch: () => exports_fetch,
|
|
15
|
+
make: () => make3
|
|
16
|
+
});
|
|
17
|
+
import { Context, Effect, Layer } from "effect";
|
|
18
|
+
import { HttpEffect, HttpMiddleware, HttpRouter, HttpServer } from "effect/unstable/http";
|
|
19
|
+
import { SessionRestart } from "@opencode/core/session/execution/restart";
|
|
20
|
+
var make3 = Effect.fn("ServerFetch.make")(function* (options = {}, boot = {}) {
|
|
21
|
+
const context = yield* Layer.build(createRoutes2(options, () => [], boot.overrides ?? []).pipe(Layer.provide(HttpServer.layerServices)));
|
|
22
|
+
yield* Effect.forkDetach(Context.get(context, SessionRestart.Service).resumeSuspendedSessions);
|
|
23
|
+
return Context.get(context, HttpRouter.HttpRouter).asHttpEffect().pipe(HttpMiddleware.cors({ allowedOrigins: (origin) => isAllowedCorsOrigin2(origin, options), maxAge: 86400 }), HttpEffect.toWebHandlerWith(context));
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
export { make3, exports_fetch };
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import {
|
|
2
|
+
missingSession2
|
|
3
|
+
} from "./process-smaf4a18.js";
|
|
4
|
+
|
|
5
|
+
// src/location.ts
|
|
6
|
+
import { Location } from "@opencode/core/location";
|
|
7
|
+
import { LocationServiceMap } from "@opencode/core/location-services";
|
|
8
|
+
import { AbsolutePath } from "@opencode/core/schema";
|
|
9
|
+
import { Session } from "@opencode/core/session";
|
|
10
|
+
import { InvalidRequestError } from "@opencode/protocol/errors";
|
|
11
|
+
import { Effect, Layer, Schema } from "effect";
|
|
12
|
+
import { HttpServerRequest } from "effect/unstable/http";
|
|
13
|
+
import { HttpApiMiddleware } from "effect/unstable/httpapi";
|
|
14
|
+
class LocationMiddleware2 extends HttpApiMiddleware.Service()("@opencode/HttpApiLocation") {
|
|
15
|
+
}
|
|
16
|
+
function response2(data) {
|
|
17
|
+
return Effect.gen(function* () {
|
|
18
|
+
const location = yield* Location.Service;
|
|
19
|
+
return {
|
|
20
|
+
location: new Location.Info({
|
|
21
|
+
directory: location.directory,
|
|
22
|
+
project: location.project
|
|
23
|
+
}),
|
|
24
|
+
data: yield* data
|
|
25
|
+
};
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
var decodeSessionID = Schema.decodeUnknownEffect(Session.ID);
|
|
29
|
+
var sessionInfo2 = Effect.fnUntraced(function* (sessions, sessionID) {
|
|
30
|
+
const id = yield* decodeSessionID(sessionID).pipe(Effect.mapError(() => new InvalidRequestError({ message: "Invalid session ID", field: "sessionID" })));
|
|
31
|
+
return yield* sessions.get(id).pipe(Effect.catchTag("Session.NotFoundError", missingSession2));
|
|
32
|
+
});
|
|
33
|
+
function requestRef2(request) {
|
|
34
|
+
const query = new URL(request.url, "http://localhost").searchParams;
|
|
35
|
+
const directory = query.get("location[directory]") || (request.headers["x-opencode-directory"] ? decode(request.headers["x-opencode-directory"]) : process.cwd());
|
|
36
|
+
return Location.Ref.make({
|
|
37
|
+
directory: AbsolutePath.make(directory)
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
function decode(input) {
|
|
41
|
+
try {
|
|
42
|
+
return decodeURIComponent(input);
|
|
43
|
+
} catch {
|
|
44
|
+
return input;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
var layer2 = Layer.effect(LocationMiddleware2, Effect.gen(function* () {
|
|
48
|
+
const locations = yield* LocationServiceMap.Service;
|
|
49
|
+
return LocationMiddleware2.of((effect) => Effect.gen(function* () {
|
|
50
|
+
const request = yield* HttpServerRequest.HttpServerRequest;
|
|
51
|
+
return yield* effect.pipe(Effect.provide(locations.get(requestRef2(request))));
|
|
52
|
+
}));
|
|
53
|
+
}));
|
|
54
|
+
|
|
55
|
+
export { LocationMiddleware2, response2, sessionInfo2, requestRef2, layer2 };
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Api2
|
|
3
|
+
} from "./process-ks9pc2xc.js";
|
|
4
|
+
import {
|
|
5
|
+
Service3,
|
|
6
|
+
frame2
|
|
7
|
+
} from "./process-d0efjmp3.js";
|
|
8
|
+
|
|
9
|
+
// src/handlers/event.ts
|
|
10
|
+
import { Event } from "@opencode/schema/event";
|
|
11
|
+
import { Effect, Stream } from "effect";
|
|
12
|
+
import { HttpServerResponse } from "effect/unstable/http";
|
|
13
|
+
import { HttpApiBuilder } from "effect/unstable/httpapi";
|
|
14
|
+
var EventHandler2 = HttpApiBuilder.group(Api2, "server.event", (handlers) => Effect.gen(function* () {
|
|
15
|
+
const feed = yield* Service3;
|
|
16
|
+
return handlers.handleRaw("event.subscribe", () => Effect.gen(function* () {
|
|
17
|
+
const connected = {
|
|
18
|
+
id: Event.ID.create(),
|
|
19
|
+
type: "server.connected",
|
|
20
|
+
data: {}
|
|
21
|
+
};
|
|
22
|
+
const output = Stream.unwrap(feed.subscribe.pipe(Effect.map((live) => Stream.make(frame2(connected)).pipe(Stream.concat(live)))));
|
|
23
|
+
const heartbeat = Stream.tick("15 seconds").pipe(Stream.map(() => `: heartbeat
|
|
24
|
+
|
|
25
|
+
`));
|
|
26
|
+
return HttpServerResponse.stream(output.pipe(Stream.merge(heartbeat, { haltStrategy: "left" }), Stream.encodeText), {
|
|
27
|
+
contentType: "text/event-stream",
|
|
28
|
+
headers: {
|
|
29
|
+
"Cache-Control": "no-cache, no-transform",
|
|
30
|
+
"X-Accel-Buffering": "no",
|
|
31
|
+
"X-Content-Type-Options": "nosniff"
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
}));
|
|
35
|
+
}));
|
|
36
|
+
|
|
37
|
+
export { EventHandler2 };
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __returnValue = (v) => v;
|
|
3
|
+
function __exportSetter(name, newValue) {
|
|
4
|
+
this[name] = __returnValue.bind(null, newValue);
|
|
5
|
+
}
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, {
|
|
9
|
+
get: all[name],
|
|
10
|
+
enumerable: true,
|
|
11
|
+
configurable: true,
|
|
12
|
+
set: __exportSetter.bind(all, name)
|
|
13
|
+
});
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export { __export };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import {
|
|
2
|
+
response2
|
|
3
|
+
} from "./process-8j6eh3dh.js";
|
|
4
|
+
import {
|
|
5
|
+
Api2
|
|
6
|
+
} from "./process-ks9pc2xc.js";
|
|
7
|
+
|
|
8
|
+
// src/handlers/reference.ts
|
|
9
|
+
import { Reference } from "@opencode/core/reference";
|
|
10
|
+
import { HttpApiBuilder } from "effect/unstable/httpapi";
|
|
11
|
+
var ReferenceHandler2 = HttpApiBuilder.group(Api2, "server.reference", (handlers) => handlers.handle("reference.list", () => response2(Reference.Service.use((reference) => reference.list()))));
|
|
12
|
+
|
|
13
|
+
export { ReferenceHandler2 };
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Api2
|
|
3
|
+
} from "./process-ks9pc2xc.js";
|
|
4
|
+
|
|
5
|
+
// src/handlers/credential.ts
|
|
6
|
+
import { Credential } from "@opencode/core/credential";
|
|
7
|
+
import { Effect } from "effect";
|
|
8
|
+
import { HttpApiBuilder, HttpApiSchema } from "effect/unstable/httpapi";
|
|
9
|
+
var CredentialHandler2 = HttpApiBuilder.group(Api2, "server.credential", (handlers) => handlers.handle("credential.update", Effect.fn(function* (ctx) {
|
|
10
|
+
const credential = yield* Credential.Service;
|
|
11
|
+
yield* credential.update(ctx.params.credentialID, { label: ctx.payload.label });
|
|
12
|
+
return HttpApiSchema.NoContent.make();
|
|
13
|
+
})).handle("credential.activate", Effect.fn(function* (ctx) {
|
|
14
|
+
const credential = yield* Credential.Service;
|
|
15
|
+
yield* credential.activate(ctx.params.credentialID);
|
|
16
|
+
return HttpApiSchema.NoContent.make();
|
|
17
|
+
})).handle("credential.remove", Effect.fn(function* (ctx) {
|
|
18
|
+
const credential = yield* Credential.Service;
|
|
19
|
+
yield* credential.remove(ctx.params.credentialID);
|
|
20
|
+
return HttpApiSchema.NoContent.make();
|
|
21
|
+
})));
|
|
22
|
+
|
|
23
|
+
export { CredentialHandler2 };
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import {
|
|
2
|
+
response2
|
|
3
|
+
} from "./process-8j6eh3dh.js";
|
|
4
|
+
import {
|
|
5
|
+
Api2
|
|
6
|
+
} from "./process-ks9pc2xc.js";
|
|
7
|
+
|
|
8
|
+
// src/handlers/form.ts
|
|
9
|
+
import { Form } from "@opencode/core/form";
|
|
10
|
+
import { Effect } from "effect";
|
|
11
|
+
import { HttpApiBuilder } from "effect/unstable/httpapi";
|
|
12
|
+
var FormHandler2 = HttpApiBuilder.group(Api2, "server.form", (handlers) => handlers.handle("form.list", Effect.fn(function* () {
|
|
13
|
+
const form = yield* Form.Service;
|
|
14
|
+
return yield* response2(form.list());
|
|
15
|
+
})));
|
|
16
|
+
|
|
17
|
+
export { FormHandler2 };
|