@opencode/server 0.0.0-dev-19794 → 0.0.0-dev-19808
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/workerd-00nn3k4b.js +20 -0
- package/dist/chunks/workerd-04xw3v55.js +23 -0
- package/dist/chunks/workerd-19c9ysa1.js +61 -0
- package/dist/chunks/workerd-1c4qas2w.js +346 -0
- package/dist/chunks/workerd-254zvkj6.js +22 -0
- package/dist/chunks/workerd-2rvsests.js +99 -0
- package/dist/chunks/workerd-2sy3c7de.js +83 -0
- package/dist/chunks/workerd-3kzx88w9.js +26 -0
- package/dist/chunks/workerd-4g0fa6m0.js +32 -0
- package/dist/chunks/workerd-4vn5bvkr.js +25 -0
- package/dist/chunks/workerd-5rwqcaw2.js +33 -0
- package/dist/chunks/workerd-5w24ch67.js +23 -0
- package/dist/chunks/workerd-6gkz39ey.js +55 -0
- package/dist/chunks/workerd-6nvan4e0.js +17 -0
- package/dist/chunks/workerd-6ptwb1q1.js +149 -0
- package/dist/chunks/workerd-75c938bc.js +23 -0
- package/dist/chunks/workerd-7cfyat0f.js +37 -0
- package/dist/chunks/workerd-7rzt3wm8.js +13 -0
- package/dist/chunks/workerd-8bajbwjh.js +40 -0
- package/dist/chunks/workerd-9rqn6x4v.js +16 -0
- package/dist/chunks/workerd-a6yp8301.js +156 -0
- package/dist/chunks/workerd-arj41x43.js +77 -0
- package/dist/chunks/workerd-b0b71rwa.js +39 -0
- package/dist/chunks/workerd-bjrwanme.js +22 -0
- package/dist/chunks/workerd-bkqymx4n.js +26 -0
- package/dist/chunks/workerd-br99j6q1.js +35 -0
- package/dist/chunks/workerd-ceh2h0m9.js +25 -0
- package/dist/chunks/workerd-hezj1jdf.js +7 -0
- package/dist/chunks/workerd-hjnxtxmk.js +34 -0
- package/dist/chunks/workerd-j2pfq4q6.js +42 -0
- package/dist/chunks/workerd-m6wvgbfq.js +60 -0
- package/dist/chunks/workerd-mzr9gftb.js +36 -0
- package/dist/chunks/workerd-n0er2m55.js +163 -0
- package/dist/chunks/workerd-pnqq1zxv.js +29 -0
- package/dist/chunks/workerd-q0ycym90.js +13 -0
- package/dist/chunks/workerd-q4bn6dy8.js +39 -0
- package/dist/chunks/workerd-qnwpcgp7.js +22 -0
- package/dist/chunks/workerd-qzap92t7.js +139 -0
- package/dist/chunks/workerd-r7e9r02j.js +13 -0
- package/dist/chunks/workerd-rcg4y18n.js +59 -0
- package/dist/chunks/workerd-req22b70.js +22 -0
- package/dist/chunks/workerd-smaf4a18.js +28 -0
- package/dist/chunks/workerd-t8yzmczr.js +18 -0
- package/dist/chunks/workerd-x1haxfjx.js +21 -0
- package/dist/chunks/workerd-yc7nft6q.js +5 -0
- package/dist/chunks/workerd-ysabas57.js +13 -0
- package/dist/chunks/workerd-z5shrcz9.js +19 -0
- package/dist/chunks/workerd-zp2jm6dt.js +15 -0
- package/dist/chunks/workerd-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
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
import {
|
|
2
|
+
response2
|
|
3
|
+
} from "./workerd-6gkz39ey.js";
|
|
4
|
+
import {
|
|
5
|
+
Api2
|
|
6
|
+
} from "./workerd-z5shrcz9.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,77 @@
|
|
|
1
|
+
import {
|
|
2
|
+
missingSession2
|
|
3
|
+
} from "./workerd-smaf4a18.js";
|
|
4
|
+
import {
|
|
5
|
+
response2,
|
|
6
|
+
sessionInfo2
|
|
7
|
+
} from "./workerd-6gkz39ey.js";
|
|
8
|
+
import {
|
|
9
|
+
Api2
|
|
10
|
+
} from "./workerd-z5shrcz9.js";
|
|
11
|
+
|
|
12
|
+
// src/handlers/permission.ts
|
|
13
|
+
import { Instance } from "@opencode/core/instance/service";
|
|
14
|
+
import { Location } from "@opencode/core/location";
|
|
15
|
+
import { Permission } from "@opencode/core/permission";
|
|
16
|
+
import { PermissionSaved } from "@opencode/core/permission/saved";
|
|
17
|
+
import { Session } from "@opencode/core/session";
|
|
18
|
+
import { Effect } from "effect";
|
|
19
|
+
import { HttpApiBuilder, HttpApiSchema } from "effect/unstable/httpapi";
|
|
20
|
+
import { PermissionNotFoundError } from "@opencode/protocol/errors";
|
|
21
|
+
function missingRequest(id) {
|
|
22
|
+
return new PermissionNotFoundError({ requestID: id, message: `Permission request not found: ${id}` });
|
|
23
|
+
}
|
|
24
|
+
var PermissionHandler2 = HttpApiBuilder.group(Api2, "server.permission", (handlers) => Effect.gen(function* () {
|
|
25
|
+
const instances = yield* Instance.Service;
|
|
26
|
+
const sessions = yield* Session.Service;
|
|
27
|
+
const requireOwnedRequest = Effect.fnUntraced(function* (sessionID, requestID) {
|
|
28
|
+
const permission = yield* Permission.Service;
|
|
29
|
+
const request = yield* permission.get(requestID);
|
|
30
|
+
if (!request || request.sessionID !== sessionID)
|
|
31
|
+
return yield* missingRequest(requestID);
|
|
32
|
+
return { permission, request };
|
|
33
|
+
});
|
|
34
|
+
return handlers.handle("permission.request.list", Effect.fn(function* () {
|
|
35
|
+
const permission = yield* Permission.Service;
|
|
36
|
+
return yield* response2(permission.list());
|
|
37
|
+
})).handle("session.permission.create", Effect.fn(function* (ctx) {
|
|
38
|
+
const permission = yield* Permission.Service;
|
|
39
|
+
return {
|
|
40
|
+
data: yield* permission.ask({
|
|
41
|
+
id: ctx.payload.id,
|
|
42
|
+
sessionID: ctx.params.sessionID,
|
|
43
|
+
action: ctx.payload.action,
|
|
44
|
+
resources: ctx.payload.resources,
|
|
45
|
+
save: ctx.payload.save,
|
|
46
|
+
metadata: ctx.payload.metadata,
|
|
47
|
+
source: ctx.payload.source,
|
|
48
|
+
agent: ctx.payload.agent
|
|
49
|
+
}).pipe(Effect.catchTag("Session.NotFoundError", missingSession2))
|
|
50
|
+
};
|
|
51
|
+
})).handle("session.permission.list", Effect.fn(function* (ctx) {
|
|
52
|
+
const session = yield* sessionInfo2(sessions, ctx.params.sessionID);
|
|
53
|
+
const requests = yield* Permission.Service.use((permission) => permission.forSession(ctx.params.sessionID)).pipe(instances.provide(session));
|
|
54
|
+
return { data: requests };
|
|
55
|
+
})).handle("session.permission.get", Effect.fn(function* (ctx) {
|
|
56
|
+
const owned = yield* requireOwnedRequest(ctx.params.sessionID, ctx.params.requestID);
|
|
57
|
+
return { data: owned.request };
|
|
58
|
+
})).handle("session.permission.reply", Effect.fn(function* (ctx) {
|
|
59
|
+
const owned = yield* requireOwnedRequest(ctx.params.sessionID, ctx.params.requestID);
|
|
60
|
+
yield* owned.permission.reply({ requestID: ctx.params.requestID, reply: ctx.payload.decision, message: ctx.payload.message }).pipe(Effect.catchTag("Permission.NotFoundError", () => missingRequest(ctx.params.requestID)));
|
|
61
|
+
return HttpApiSchema.NoContent.make();
|
|
62
|
+
})).handle("permission.saved.list", Effect.fn(function* (ctx) {
|
|
63
|
+
const location = yield* Location.Service;
|
|
64
|
+
const saved = yield* PermissionSaved.Service;
|
|
65
|
+
return {
|
|
66
|
+
data: yield* saved.list({
|
|
67
|
+
projectID: ctx.query.projectID ?? location.project.id
|
|
68
|
+
})
|
|
69
|
+
};
|
|
70
|
+
})).handle("permission.saved.remove", Effect.fn(function* (ctx) {
|
|
71
|
+
const saved = yield* PermissionSaved.Service;
|
|
72
|
+
yield* saved.remove(ctx.params.id);
|
|
73
|
+
return HttpApiSchema.NoContent.make();
|
|
74
|
+
}));
|
|
75
|
+
}));
|
|
76
|
+
|
|
77
|
+
export { PermissionHandler2 };
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import {
|
|
2
|
+
response2
|
|
3
|
+
} from "./workerd-6gkz39ey.js";
|
|
4
|
+
import {
|
|
5
|
+
Api2
|
|
6
|
+
} from "./workerd-z5shrcz9.js";
|
|
7
|
+
|
|
8
|
+
// src/handlers/websearch.ts
|
|
9
|
+
import { WebSearch } from "@opencode/core/websearch";
|
|
10
|
+
import { InvalidRequestError, ServiceUnavailableError } from "@opencode/protocol/errors";
|
|
11
|
+
import { Effect } from "effect";
|
|
12
|
+
import { HttpApiBuilder } from "effect/unstable/httpapi";
|
|
13
|
+
var WebSearchHandler2 = HttpApiBuilder.group(Api2, "server.websearch", (handlers) => Effect.gen(function* () {
|
|
14
|
+
return handlers.handle("websearch.providers", Effect.fn("server.websearch.providers")(function* () {
|
|
15
|
+
const websearch = yield* WebSearch.Service;
|
|
16
|
+
return yield* response2(websearch.providers());
|
|
17
|
+
})).handle("websearch.query", Effect.fn("server.websearch.query")(function* (request) {
|
|
18
|
+
const websearch = yield* WebSearch.Service;
|
|
19
|
+
return yield* response2(websearch.query(request.payload).pipe(Effect.catchTags({
|
|
20
|
+
"WebSearch.ProviderRequired": () => new InvalidRequestError({
|
|
21
|
+
message: "Web search provider is required",
|
|
22
|
+
kind: "websearch_provider_required",
|
|
23
|
+
field: "providerID"
|
|
24
|
+
}),
|
|
25
|
+
"WebSearch.ProviderNotFound": (error) => new InvalidRequestError({
|
|
26
|
+
message: `Web search provider not found: ${error.providerID}`,
|
|
27
|
+
kind: "websearch_provider_not_found",
|
|
28
|
+
field: "providerID"
|
|
29
|
+
}),
|
|
30
|
+
"WebSearch.Disabled": () => new InvalidRequestError({ message: "Web search is disabled", kind: "websearch_disabled" }),
|
|
31
|
+
"WebSearch.Request": (error) => new ServiceUnavailableError({
|
|
32
|
+
message: `Web search request failed: ${error.providerID}`,
|
|
33
|
+
service: error.providerID
|
|
34
|
+
})
|
|
35
|
+
})));
|
|
36
|
+
}));
|
|
37
|
+
}));
|
|
38
|
+
|
|
39
|
+
export { WebSearchHandler2 };
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Api2
|
|
3
|
+
} from "./workerd-z5shrcz9.js";
|
|
4
|
+
|
|
5
|
+
// src/handlers/rpc.ts
|
|
6
|
+
import { Rpc } from "@opencode/core/rpc";
|
|
7
|
+
import { Plugin } from "@opencode/core/plugin";
|
|
8
|
+
import { RpcError, RpcInternalError } from "@opencode/protocol/errors";
|
|
9
|
+
import { Effect } from "effect";
|
|
10
|
+
import { HttpApiBuilder } from "effect/unstable/httpapi";
|
|
11
|
+
var RpcHandler2 = HttpApiBuilder.group(Api2, "server.rpc", (handlers) => handlers.handle("rpc.call", ({ params, payload }) => Effect.gen(function* () {
|
|
12
|
+
yield* Plugin.awaitActivation;
|
|
13
|
+
const rpc = yield* Rpc.Service;
|
|
14
|
+
const output = yield* rpc.call(params.rpcID, params.method, payload.input);
|
|
15
|
+
return output === undefined ? {} : { output };
|
|
16
|
+
}).pipe(Effect.mapError((error) => error.type === "rpc.invalid_output" || error.type === "rpc.internal" ? new RpcInternalError({ type: error.type, message: error.message }) : new RpcError({
|
|
17
|
+
type: error.type,
|
|
18
|
+
message: error.message,
|
|
19
|
+
...error.data === undefined ? {} : { data: error.data }
|
|
20
|
+
})), Effect.catchDefect((defect) => Effect.logError("rpc call failed", { rpc: params.rpcID, method: params.method, defect }).pipe(Effect.andThen(Effect.fail(new RpcInternalError({ type: "rpc.internal", message: "RPC call failed" }))))))));
|
|
21
|
+
|
|
22
|
+
export { RpcHandler2 };
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import {
|
|
2
|
+
isAllowedCorsOrigin2
|
|
3
|
+
} from "./workerd-q4bn6dy8.js";
|
|
4
|
+
import {
|
|
5
|
+
createRoutes2
|
|
6
|
+
} from "./workerd-6ptwb1q1.js";
|
|
7
|
+
import {
|
|
8
|
+
__export
|
|
9
|
+
} from "./workerd-9rqn6x4v.js";
|
|
10
|
+
|
|
11
|
+
// src/fetch.ts
|
|
12
|
+
var exports_fetch = {};
|
|
13
|
+
__export(exports_fetch, {
|
|
14
|
+
ServerFetch: () => exports_fetch,
|
|
15
|
+
make: () => make2
|
|
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 make2 = 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 { make2, exports_fetch };
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import {
|
|
2
|
+
response2
|
|
3
|
+
} from "./workerd-6gkz39ey.js";
|
|
4
|
+
import {
|
|
5
|
+
Api2
|
|
6
|
+
} from "./workerd-z5shrcz9.js";
|
|
7
|
+
|
|
8
|
+
// src/handlers/shell.ts
|
|
9
|
+
import { Shell } from "@opencode/core/shell";
|
|
10
|
+
import { Location } from "@opencode/core/location";
|
|
11
|
+
import { Effect } from "effect";
|
|
12
|
+
import { HttpApiBuilder, HttpApiSchema } from "effect/unstable/httpapi";
|
|
13
|
+
import { ShellNotFoundError } from "@opencode/protocol/errors";
|
|
14
|
+
var ShellHandler2 = HttpApiBuilder.group(Api2, "server.shell", (handlers) => Effect.gen(function* () {
|
|
15
|
+
return handlers.handle("shell.list", Effect.fn(function* () {
|
|
16
|
+
const shell = yield* Shell.Service;
|
|
17
|
+
return yield* response2(shell.list());
|
|
18
|
+
})).handle("shell.create", Effect.fn(function* (ctx) {
|
|
19
|
+
const shell = yield* Shell.Service;
|
|
20
|
+
const location = yield* Location.Service;
|
|
21
|
+
return yield* response2(shell.create({ ...ctx.payload, cwd: ctx.payload.cwd || location.directory }).pipe(Effect.orDie));
|
|
22
|
+
})).handle("shell.get", Effect.fn(function* (ctx) {
|
|
23
|
+
const shell = yield* Shell.Service;
|
|
24
|
+
return yield* response2(shell.get(ctx.params.id).pipe(Effect.catchTag("Shell.NotFoundError", () => new ShellNotFoundError({ id: ctx.params.id, message: `Shell command not found: ${ctx.params.id}` }))));
|
|
25
|
+
})).handle("shell.output", Effect.fn(function* (ctx) {
|
|
26
|
+
const shell = yield* Shell.Service;
|
|
27
|
+
return yield* response2(shell.output(ctx.params.id, { cursor: ctx.query.cursor, limit: ctx.query.limit }).pipe(Effect.catchTag("Shell.NotFoundError", () => new ShellNotFoundError({ id: ctx.params.id, message: `Shell command not found: ${ctx.params.id}` }))));
|
|
28
|
+
})).handle("shell.remove", Effect.fn(function* (ctx) {
|
|
29
|
+
const shell = yield* Shell.Service;
|
|
30
|
+
yield* shell.remove(ctx.params.id).pipe(Effect.catchTag("Shell.NotFoundError", () => Effect.void));
|
|
31
|
+
return HttpApiSchema.NoContent.make();
|
|
32
|
+
}));
|
|
33
|
+
}));
|
|
34
|
+
|
|
35
|
+
export { ShellHandler2 };
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import {
|
|
2
|
+
response2
|
|
3
|
+
} from "./workerd-6gkz39ey.js";
|
|
4
|
+
import {
|
|
5
|
+
Api2
|
|
6
|
+
} from "./workerd-z5shrcz9.js";
|
|
7
|
+
|
|
8
|
+
// src/handlers/agent.ts
|
|
9
|
+
import { Agent } from "@opencode/core/agent";
|
|
10
|
+
import { Effect } from "effect";
|
|
11
|
+
import { HttpApiBuilder } from "effect/unstable/httpapi";
|
|
12
|
+
import { AgentNotFoundError } from "@opencode/protocol/errors";
|
|
13
|
+
var AgentHandler2 = HttpApiBuilder.group(Api2, "server.agent", (handlers) => handlers.handle("agent.list", () => Effect.gen(function* () {
|
|
14
|
+
return yield* response2(Agent.Service.use((agent) => agent.list()));
|
|
15
|
+
})).handle("agent.get", Effect.fn(function* (ctx) {
|
|
16
|
+
const agent = yield* Agent.Service.use((service) => service.get(ctx.params.agentID));
|
|
17
|
+
if (!agent)
|
|
18
|
+
return yield* new AgentNotFoundError({
|
|
19
|
+
agentID: ctx.params.agentID,
|
|
20
|
+
message: `Agent not found: ${ctx.params.agentID}`
|
|
21
|
+
});
|
|
22
|
+
return yield* response2(Effect.succeed(agent));
|
|
23
|
+
})));
|
|
24
|
+
|
|
25
|
+
export { AgentHandler2 };
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import {
|
|
2
|
+
response2
|
|
3
|
+
} from "./workerd-6gkz39ey.js";
|
|
4
|
+
import {
|
|
5
|
+
Api2
|
|
6
|
+
} from "./workerd-z5shrcz9.js";
|
|
7
|
+
|
|
8
|
+
// src/handlers/fs.ts
|
|
9
|
+
import { FileSystem } from "@opencode/core/filesystem";
|
|
10
|
+
import { RelativePath } from "@opencode/core/schema";
|
|
11
|
+
import { FileNotFoundError } from "@opencode/protocol/errors";
|
|
12
|
+
import { Effect } from "effect";
|
|
13
|
+
import { HttpServerResponse } from "effect/unstable/http";
|
|
14
|
+
import { HttpApiBuilder } from "effect/unstable/httpapi";
|
|
15
|
+
var FileSystemHandler2 = HttpApiBuilder.group(Api2, "server.fs", (handlers) => Effect.gen(function* () {
|
|
16
|
+
return handlers.handleRaw("fs.read", (ctx) => Effect.gen(function* () {
|
|
17
|
+
const fs = yield* FileSystem.Service;
|
|
18
|
+
const file = yield* fs.read({
|
|
19
|
+
path: RelativePath.make(decodeURIComponent(new URL(ctx.request.url, "http://localhost").pathname.slice(13)))
|
|
20
|
+
}).pipe(Effect.mapError((error) => new FileNotFoundError({ path: error.path, message: `File not found: ${error.path}` })));
|
|
21
|
+
return HttpServerResponse.uint8Array(file.content, { contentType: file.mime });
|
|
22
|
+
})).handle("fs.list", (ctx) => response2(Effect.gen(function* () {
|
|
23
|
+
const fs = yield* FileSystem.Service;
|
|
24
|
+
return yield* fs.list(ctx.query);
|
|
25
|
+
}))).handle("fs.find", (ctx) => response2(Effect.gen(function* () {
|
|
26
|
+
const fs = yield* FileSystem.Service;
|
|
27
|
+
return yield* fs.find(ctx.query);
|
|
28
|
+
}))).handle("fs.write", (ctx) => response2(Effect.gen(function* () {
|
|
29
|
+
const fs = yield* FileSystem.Service;
|
|
30
|
+
return yield* fs.write({ path: ctx.query.path, data: ctx.payload });
|
|
31
|
+
})));
|
|
32
|
+
}));
|
|
33
|
+
|
|
34
|
+
export { FileSystemHandler2 };
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Api2
|
|
3
|
+
} from "./workerd-z5shrcz9.js";
|
|
4
|
+
|
|
5
|
+
// src/handlers/worktree.ts
|
|
6
|
+
import { Git } from "@opencode/core/git";
|
|
7
|
+
import { Worktree } from "@opencode/core/worktree";
|
|
8
|
+
import { ProjectNotFoundError } from "@opencode/protocol/errors";
|
|
9
|
+
import { WorktreeError } from "@opencode/protocol/groups/worktree";
|
|
10
|
+
import { Effect } from "effect";
|
|
11
|
+
import { HttpApiBuilder, HttpApiSchema } from "effect/unstable/httpapi";
|
|
12
|
+
var WorktreeHandler2 = HttpApiBuilder.group(Api2, "server.worktree", (handlers) => Effect.gen(function* () {
|
|
13
|
+
const worktrees = yield* Worktree.Service;
|
|
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
|
+
}));
|
|
16
|
+
function badRequest(effect) {
|
|
17
|
+
return effect.pipe(Effect.catchTag("Project.NotFoundError", missingProject), Effect.mapError((error) => error instanceof ProjectNotFoundError ? error : new WorktreeError({
|
|
18
|
+
name: "WorktreeError",
|
|
19
|
+
data: {
|
|
20
|
+
message: message(error),
|
|
21
|
+
forceRequired: error instanceof Git.WorktreeError || error instanceof Worktree.OperationError ? error.forceRequired : undefined
|
|
22
|
+
}
|
|
23
|
+
})));
|
|
24
|
+
}
|
|
25
|
+
function missingProject(error) {
|
|
26
|
+
return Effect.fail(new ProjectNotFoundError({ projectID: error.projectID, message: `Project not found: ${error.projectID}` }));
|
|
27
|
+
}
|
|
28
|
+
function message(error) {
|
|
29
|
+
if (error instanceof Worktree.SourceDirectoryNotFoundError)
|
|
30
|
+
return error.directory ? `Worktree source not found: ${error.directory}` : `Worktree source not found for project: ${error.projectID}`;
|
|
31
|
+
if (error instanceof Worktree.DestinationExistsError)
|
|
32
|
+
return `Worktree destination already exists: ${error.directory}`;
|
|
33
|
+
if (error instanceof Worktree.DirectoryUnavailableError)
|
|
34
|
+
return `Worktree directory unavailable: ${error.directory}`;
|
|
35
|
+
if (error instanceof Worktree.InvalidDirectoryError)
|
|
36
|
+
return `Invalid worktree directory: ${error.directory}`;
|
|
37
|
+
if (error instanceof Worktree.StrategyUnavailableError)
|
|
38
|
+
return `Worktree strategy unavailable: ${error.strategy}`;
|
|
39
|
+
return error.message;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export { WorktreeHandler2 };
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Config2,
|
|
3
|
+
required2,
|
|
4
|
+
authorized2
|
|
5
|
+
} from "./workerd-zyv89x5n.js";
|
|
6
|
+
|
|
7
|
+
// src/middleware/authorization.ts
|
|
8
|
+
import { UnauthorizedError } from "@opencode/protocol/errors";
|
|
9
|
+
import { Authorization } from "@opencode/protocol/middleware/authorization";
|
|
10
|
+
import { Authorization as Authorization2 } from "@opencode/protocol/middleware/authorization";
|
|
11
|
+
import { hasPtyConnectTicketURL } from "@opencode/protocol/groups/pty";
|
|
12
|
+
import { hasPersistentPtyConnectTicketURL } from "@opencode/protocol/groups/persistent-pty";
|
|
13
|
+
import { Effect, Encoding, Layer, Redacted } from "effect";
|
|
14
|
+
import { HttpEffect, HttpServerRequest, HttpServerResponse } from "effect/unstable/http";
|
|
15
|
+
var AUTH_TOKEN_QUERY = "auth_token";
|
|
16
|
+
var WWW_AUTHENTICATE = 'Basic realm="Secure Area"';
|
|
17
|
+
function emptyCredential() {
|
|
18
|
+
return { username: "", password: Redacted.make("") };
|
|
19
|
+
}
|
|
20
|
+
function decodeCredential(input) {
|
|
21
|
+
return Effect.fromResult(Encoding.decodeBase64String(input)).pipe(Effect.match({
|
|
22
|
+
onFailure: emptyCredential,
|
|
23
|
+
onSuccess: (header) => {
|
|
24
|
+
const separator = header.indexOf(":");
|
|
25
|
+
if (separator === -1)
|
|
26
|
+
return emptyCredential();
|
|
27
|
+
return { username: header.slice(0, separator), password: Redacted.make(header.slice(separator + 1)) };
|
|
28
|
+
}
|
|
29
|
+
}));
|
|
30
|
+
}
|
|
31
|
+
function credentialFromRequest(request) {
|
|
32
|
+
const url = new URL(request.url, "http://localhost");
|
|
33
|
+
const token = url.searchParams.get(AUTH_TOKEN_QUERY);
|
|
34
|
+
if (token)
|
|
35
|
+
return decodeCredential(token);
|
|
36
|
+
const match = /^Basic\s+(.+)$/i.exec(request.headers.authorization ?? "");
|
|
37
|
+
if (match)
|
|
38
|
+
return decodeCredential(match[1]);
|
|
39
|
+
return Effect.succeed(emptyCredential());
|
|
40
|
+
}
|
|
41
|
+
function authorizedRequest2(request, config) {
|
|
42
|
+
return credentialFromRequest(request).pipe(Effect.map((credential) => authorized2(credential, config)));
|
|
43
|
+
}
|
|
44
|
+
var authorizationLayer2 = Layer.effect(Authorization, Effect.gen(function* () {
|
|
45
|
+
const config = yield* Config2;
|
|
46
|
+
if (!required2(config))
|
|
47
|
+
return Authorization.of((effect) => effect);
|
|
48
|
+
return Authorization.of((effect) => Effect.gen(function* () {
|
|
49
|
+
const request = yield* HttpServerRequest.HttpServerRequest;
|
|
50
|
+
const url = new URL(request.url, "http://localhost");
|
|
51
|
+
if (hasPtyConnectTicketURL(url) || hasPersistentPtyConnectTicketURL(url))
|
|
52
|
+
return yield* effect;
|
|
53
|
+
if (yield* authorizedRequest2(request, config))
|
|
54
|
+
return yield* effect;
|
|
55
|
+
yield* HttpEffect.appendPreResponseHandler((_request, response) => Effect.succeed(HttpServerResponse.setHeader(response, "www-authenticate", WWW_AUTHENTICATE)));
|
|
56
|
+
return yield* new UnauthorizedError({ message: "Authentication required" });
|
|
57
|
+
}));
|
|
58
|
+
}));
|
|
59
|
+
|
|
60
|
+
export { authorizedRequest2, authorizationLayer2, Authorization2 };
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import {
|
|
2
|
+
__export
|
|
3
|
+
} from "./workerd-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: () => Service3,
|
|
10
|
+
connectionURLs: () => connectionURLs2,
|
|
11
|
+
layer: () => layer3
|
|
12
|
+
});
|
|
13
|
+
import { Context, Layer } from "effect";
|
|
14
|
+
import { networkInterfaces } from "node:os";
|
|
15
|
+
|
|
16
|
+
class Service3 extends Context.Service()("@opencode/server/ServerInfo") {
|
|
17
|
+
}
|
|
18
|
+
function layer3(urls, tmp, app = {}) {
|
|
19
|
+
return Layer.succeed(Service3, Service3.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 { Service3, layer3, connectionURLs2, exports_server_info };
|