@zyraxon-ai/server 19.0.4 → 19.0.5

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 (143) hide show
  1. package/dist/api.d.ts +2 -0
  2. package/dist/api.d.ts.map +1 -0
  3. package/dist/api.js +8 -0
  4. package/dist/api.js.map +1 -0
  5. package/dist/auth.d.ts +26 -0
  6. package/dist/auth.d.ts.map +1 -0
  7. package/dist/auth.js +36 -0
  8. package/dist/auth.js.map +1 -0
  9. package/dist/cors.d.ts +8 -0
  10. package/dist/cors.d.ts.map +1 -0
  11. package/dist/cors.js +36 -0
  12. package/dist/cors.js.map +1 -0
  13. package/dist/handlers/agent.d.ts +2 -0
  14. package/dist/handlers/agent.d.ts.map +1 -0
  15. package/dist/handlers/agent.js +9 -0
  16. package/dist/handlers/agent.js.map +1 -0
  17. package/dist/handlers/command.d.ts +2 -0
  18. package/dist/handlers/command.d.ts.map +1 -0
  19. package/dist/handlers/command.js +6 -0
  20. package/dist/handlers/command.js.map +1 -0
  21. package/dist/handlers/credential.d.ts +2 -0
  22. package/dist/handlers/credential.d.ts.map +1 -0
  23. package/dist/handlers/credential.js +14 -0
  24. package/dist/handlers/credential.js.map +1 -0
  25. package/dist/handlers/event.d.ts +2 -0
  26. package/dist/handlers/event.d.ts.map +1 -0
  27. package/dist/handlers/event.js +41 -0
  28. package/dist/handlers/event.js.map +1 -0
  29. package/dist/handlers/fs.d.ts +2 -0
  30. package/dist/handlers/fs.d.ts.map +1 -0
  31. package/dist/handlers/fs.js +25 -0
  32. package/dist/handlers/fs.js.map +1 -0
  33. package/dist/handlers/health.d.ts +2 -0
  34. package/dist/handlers/health.d.ts.map +1 -0
  35. package/dist/handlers/health.js +5 -0
  36. package/dist/handlers/health.js.map +1 -0
  37. package/dist/handlers/integration.d.ts +2 -0
  38. package/dist/handlers/integration.d.ts.map +1 -0
  39. package/dist/handlers/integration.js +61 -0
  40. package/dist/handlers/integration.js.map +1 -0
  41. package/dist/handlers/location.d.ts +2 -0
  42. package/dist/handlers/location.d.ts.map +1 -0
  43. package/dist/handlers/location.js +13 -0
  44. package/dist/handlers/location.js.map +1 -0
  45. package/dist/handlers/message.d.ts +2 -0
  46. package/dist/handlers/message.d.ts.map +1 -0
  47. package/dist/handlers/message.js +57 -0
  48. package/dist/handlers/message.js.map +1 -0
  49. package/dist/handlers/model.d.ts +2 -0
  50. package/dist/handlers/model.d.ts.map +1 -0
  51. package/dist/handlers/model.js +12 -0
  52. package/dist/handlers/model.js.map +1 -0
  53. package/dist/handlers/permission.d.ts +2 -0
  54. package/dist/handlers/permission.d.ts.map +1 -0
  55. package/dist/handlers/permission.js +70 -0
  56. package/dist/handlers/permission.js.map +1 -0
  57. package/dist/handlers/project-copy.d.ts +2 -0
  58. package/dist/handlers/project-copy.d.ts.map +1 -0
  59. package/dist/handlers/project-copy.js +42 -0
  60. package/dist/handlers/project-copy.js.map +1 -0
  61. package/dist/handlers/provider.d.ts +2 -0
  62. package/dist/handlers/provider.d.ts.map +1 -0
  63. package/dist/handlers/provider.js +24 -0
  64. package/dist/handlers/provider.js.map +1 -0
  65. package/dist/handlers/pty.d.ts +2 -0
  66. package/dist/handlers/pty.d.ts.map +1 -0
  67. package/dist/handlers/pty.js +142 -0
  68. package/dist/handlers/pty.js.map +1 -0
  69. package/dist/handlers/question.d.ts +2 -0
  70. package/dist/handlers/question.d.ts.map +1 -0
  71. package/dist/handlers/question.js +39 -0
  72. package/dist/handlers/question.js.map +1 -0
  73. package/dist/handlers/reference.d.ts +2 -0
  74. package/dist/handlers/reference.d.ts.map +1 -0
  75. package/dist/handlers/reference.js +6 -0
  76. package/dist/handlers/reference.js.map +1 -0
  77. package/dist/handlers/session.d.ts +2 -0
  78. package/dist/handlers/session.d.ts.map +1 -0
  79. package/dist/handlers/session.js +206 -0
  80. package/dist/handlers/session.js.map +1 -0
  81. package/dist/handlers/skill.d.ts +2 -0
  82. package/dist/handlers/skill.d.ts.map +1 -0
  83. package/dist/handlers/skill.js +6 -0
  84. package/dist/handlers/skill.js.map +1 -0
  85. package/dist/handlers.d.ts +3 -0
  86. package/dist/handlers.d.ts.map +1 -0
  87. package/dist/handlers.js +21 -0
  88. package/dist/handlers.js.map +1 -0
  89. package/dist/location.d.ts +21 -0
  90. package/dist/location.d.ts.map +1 -0
  91. package/dist/location.js +48 -0
  92. package/dist/location.js.map +1 -0
  93. package/dist/middleware/authorization.d.ts +6 -0
  94. package/dist/middleware/authorization.d.ts.map +1 -0
  95. package/dist/middleware/authorization.js +51 -0
  96. package/dist/middleware/authorization.js.map +1 -0
  97. package/dist/middleware/schema-error.d.ts +4 -0
  98. package/dist/middleware/schema-error.d.ts.map +1 -0
  99. package/dist/middleware/schema-error.js +16 -0
  100. package/dist/middleware/schema-error.js.map +1 -0
  101. package/dist/middleware/session-location.d.ts +16 -0
  102. package/dist/middleware/session-location.d.ts.map +1 -0
  103. package/dist/middleware/session-location.js +44 -0
  104. package/dist/middleware/session-location.js.map +1 -0
  105. package/dist/pty-environment.d.ts +14 -0
  106. package/dist/pty-environment.d.ts.map +1 -0
  107. package/dist/pty-environment.js +10 -0
  108. package/dist/pty-environment.js.map +1 -0
  109. package/dist/routes.d.ts +9 -0
  110. package/dist/routes.d.ts.map +1 -0
  111. package/dist/routes.js +51 -0
  112. package/dist/routes.js.map +1 -0
  113. package/package.json +10 -6
  114. package/src/api.ts +0 -8
  115. package/src/auth.ts +0 -63
  116. package/src/cors.ts +0 -34
  117. package/src/handlers/agent.ts +0 -13
  118. package/src/handlers/command.ts +0 -8
  119. package/src/handlers/credential.ts +0 -22
  120. package/src/handlers/event.ts +0 -52
  121. package/src/handlers/fs.ts +0 -39
  122. package/src/handlers/health.ts +0 -7
  123. package/src/handlers/integration.ts +0 -104
  124. package/src/handlers/location.ts +0 -18
  125. package/src/handlers/message.ts +0 -81
  126. package/src/handlers/model.ts +0 -17
  127. package/src/handlers/permission.ts +0 -98
  128. package/src/handlers/project-copy.ts +0 -68
  129. package/src/handlers/provider.ts +0 -32
  130. package/src/handlers/pty.ts +0 -223
  131. package/src/handlers/question.ts +0 -62
  132. package/src/handlers/reference.ts +0 -8
  133. package/src/handlers/session.ts +0 -385
  134. package/src/handlers/skill.ts +0 -8
  135. package/src/handlers.ts +0 -40
  136. package/src/location.ts +0 -60
  137. package/src/middleware/authorization.ts +0 -58
  138. package/src/middleware/schema-error.ts +0 -20
  139. package/src/middleware/session-location.ts +0 -67
  140. package/src/pty-environment.ts +0 -19
  141. package/src/routes.ts +0 -68
  142. package/sst-env.d.ts +0 -10
  143. package/tsconfig.json +0 -8
@@ -1,8 +0,0 @@
1
- import { CommandV2 } from "@zyraxon-ai/core/command"
2
- import { HttpApiBuilder } from "effect/unstable/httpapi"
3
- import { Api } from "../api"
4
- import { response } from "../location"
5
-
6
- export const CommandHandler = HttpApiBuilder.group(Api, "server.command", (handlers) =>
7
- handlers.handle("command.list", () => response(CommandV2.Service.use((command) => command.list()))),
8
- )
@@ -1,22 +0,0 @@
1
- import { Integration } from "@zyraxon-ai/core/integration"
2
- import { Effect } from "effect"
3
- import { HttpApiBuilder, HttpApiSchema } from "effect/unstable/httpapi"
4
- import { Api } from "../api"
5
-
6
- export const CredentialHandler = HttpApiBuilder.group(Api, "server.credential", (handlers) =>
7
- handlers
8
- .handle(
9
- "credential.update",
10
- Effect.fn(function* (ctx) {
11
- yield* (yield* Integration.Service).connection.update(ctx.params.credentialID, { label: ctx.payload.label })
12
- return HttpApiSchema.NoContent.make()
13
- }),
14
- )
15
- .handle(
16
- "credential.remove",
17
- Effect.fn(function* (ctx) {
18
- yield* (yield* Integration.Service).connection.remove(ctx.params.credentialID)
19
- return HttpApiSchema.NoContent.make()
20
- }),
21
- ),
22
- )
@@ -1,52 +0,0 @@
1
- import { EventV2 } from "@zyraxon-ai/core/event"
2
- import { ZyraxonEvent } from "@zyraxon-ai/protocol/groups/event"
3
- import { Effect, Schema, Stream } from "effect"
4
- import { HttpServerResponse } from "effect/unstable/http"
5
- import { HttpApiBuilder } from "effect/unstable/httpapi"
6
- import * as Sse from "effect/unstable/encoding/Sse"
7
- import { Api } from "../api"
8
-
9
- const subscriberCapacity = 256
10
-
11
- function eventData(data: unknown): Sse.Event {
12
- return {
13
- _tag: "Event",
14
- event: "message",
15
- id: undefined,
16
- data: JSON.stringify(Schema.encodeUnknownSync(ZyraxonEvent)(data)),
17
- }
18
- }
19
-
20
- export const EventHandler = HttpApiBuilder.group(Api, "server.event", (handlers) =>
21
- Effect.gen(function* () {
22
- const events = yield* EventV2.Service
23
- return handlers.handleRaw("event.subscribe", () =>
24
- Effect.gen(function* () {
25
- const connected = {
26
- id: EventV2.ID.create(),
27
- type: "server.connected",
28
- data: {},
29
- }
30
- const output = Stream.unwrap(
31
- Effect.gen(function* () {
32
- // Acquiring the bounded stream installs its listener before readiness is observable.
33
- const live = yield* EventV2.allBounded(events, subscriberCapacity)
34
- return Stream.make(connected).pipe(Stream.concat(live))
35
- }),
36
- ).pipe(Stream.map(eventData), Stream.pipeThroughChannel(Sse.encode()))
37
- const heartbeat = Stream.tick("15 seconds").pipe(Stream.map(() => ": heartbeat\n\n"))
38
- return HttpServerResponse.stream(
39
- output.pipe(Stream.merge(heartbeat, { haltStrategy: "left" }), Stream.encodeText),
40
- {
41
- contentType: "text/event-stream",
42
- headers: {
43
- "Cache-Control": "no-cache, no-transform",
44
- "X-Accel-Buffering": "no",
45
- "X-Content-Type-Options": "nosniff",
46
- },
47
- },
48
- )
49
- }),
50
- )
51
- }),
52
- )
@@ -1,39 +0,0 @@
1
- import { FileSystem } from "@zyraxon-ai/core/filesystem"
2
- import { RelativePath } from "@zyraxon-ai/core/schema"
3
- import { Effect } from "effect"
4
- import { HttpServerResponse } from "effect/unstable/http"
5
- import { HttpApiBuilder } from "effect/unstable/httpapi"
6
- import { Api } from "../api"
7
- import { response } from "../location"
8
-
9
- export const FileSystemHandler = HttpApiBuilder.group(Api, "server.fs", (handlers) =>
10
- Effect.gen(function* () {
11
- return handlers
12
- .handleRaw("fs.read", (ctx) =>
13
- Effect.gen(function* () {
14
- const file = yield* (yield* FileSystem.Service).read({
15
- path: RelativePath.make(
16
- decodeURIComponent(new URL(ctx.request.url, "http://localhost").pathname.slice(13)),
17
- ),
18
- })
19
- return HttpServerResponse.uint8Array(file.content, { contentType: file.mime })
20
- }),
21
- )
22
- .handle("fs.list", (ctx) =>
23
- response(
24
- Effect.gen(function* () {
25
- const fs = yield* FileSystem.Service
26
- return yield* fs.list(ctx.query)
27
- }),
28
- ),
29
- )
30
- .handle("fs.find", (ctx) =>
31
- response(
32
- Effect.gen(function* () {
33
- const fs = yield* FileSystem.Service
34
- return yield* fs.find(ctx.query)
35
- }),
36
- ),
37
- )
38
- }),
39
- )
@@ -1,7 +0,0 @@
1
- import { Effect } from "effect"
2
- import { HttpApiBuilder } from "effect/unstable/httpapi"
3
- import { Api } from "../api"
4
-
5
- export const HealthHandler = HttpApiBuilder.group(Api, "server.health", (handlers) =>
6
- handlers.handle("health.get", () => Effect.succeed({ healthy: true as const })),
7
- )
@@ -1,104 +0,0 @@
1
- import { Integration } from "@zyraxon-ai/core/integration"
2
- import { Effect } from "effect"
3
- import { HttpApiBuilder, HttpApiSchema } from "effect/unstable/httpapi"
4
- import { Api } from "../api"
5
- import { InvalidRequestError } from "@zyraxon-ai/protocol/errors"
6
- import { response } from "../location"
7
-
8
- const authorize = <A, R>(effect: Effect.Effect<A, Integration.AuthorizationError, R>) =>
9
- effect.pipe(
10
- Effect.mapError(
11
- () =>
12
- new InvalidRequestError({
13
- message: "Authentication failed",
14
- kind: "integration_authorization",
15
- }),
16
- ),
17
- )
18
-
19
- export const IntegrationHandler = HttpApiBuilder.group(Api, "server.integration", (handlers) =>
20
- Effect.gen(function* () {
21
- return handlers
22
- .handle(
23
- "integration.list",
24
- Effect.fn(function* () {
25
- const service = yield* Integration.Service
26
- return yield* response(service.list())
27
- }),
28
- )
29
- .handle(
30
- "integration.get",
31
- Effect.fn(function* (ctx) {
32
- const service = yield* Integration.Service
33
- return yield* response(service.get(ctx.params.integrationID))
34
- }),
35
- )
36
- .handle(
37
- "integration.connect.key",
38
- Effect.fn(function* (ctx) {
39
- const service = yield* Integration.Service
40
- yield* authorize(
41
- service.connection.key({
42
- integrationID: ctx.params.integrationID,
43
- key: ctx.payload.key,
44
- label: ctx.payload.label,
45
- }),
46
- )
47
- return HttpApiSchema.NoContent.make()
48
- }),
49
- )
50
- .handle(
51
- "integration.connect.oauth",
52
- Effect.fn(function* (ctx) {
53
- const service = yield* Integration.Service
54
- return yield* response(
55
- authorize(
56
- service.connection.oauth({
57
- integrationID: ctx.params.integrationID,
58
- methodID: ctx.payload.methodID,
59
- inputs: ctx.payload.inputs,
60
- label: ctx.payload.label,
61
- }),
62
- ),
63
- )
64
- }),
65
- )
66
- .handle(
67
- "integration.attempt.status",
68
- Effect.fn(function* (ctx) {
69
- const service = yield* Integration.Service
70
- return yield* response(service.attempt.status(ctx.params.attemptID))
71
- }),
72
- )
73
- .handle(
74
- "integration.attempt.complete",
75
- Effect.fn(function* (ctx) {
76
- const service = yield* Integration.Service
77
- yield* service.attempt.complete({ attemptID: ctx.params.attemptID, code: ctx.payload.code }).pipe(
78
- Effect.mapError(
79
- (error) =>
80
- new InvalidRequestError({
81
- message:
82
- error._tag === "Integration.CodeRequired"
83
- ? "Authorization code is required"
84
- : "Authentication failed",
85
- kind:
86
- error._tag === "Integration.CodeRequired"
87
- ? "integration_code_required"
88
- : "integration_authorization",
89
- }),
90
- ),
91
- )
92
- return HttpApiSchema.NoContent.make()
93
- }),
94
- )
95
- .handle(
96
- "integration.attempt.cancel",
97
- Effect.fn(function* (ctx) {
98
- const service = yield* Integration.Service
99
- yield* service.attempt.cancel(ctx.params.attemptID)
100
- return HttpApiSchema.NoContent.make()
101
- }),
102
- )
103
- }),
104
- )
@@ -1,18 +0,0 @@
1
- import { Location } from "@zyraxon-ai/core/location"
2
- import { Effect } from "effect"
3
- import { HttpApiBuilder } from "effect/unstable/httpapi"
4
- import { Api } from "../api"
5
-
6
- export const LocationHandler = HttpApiBuilder.group(Api, "server.location", (handlers) =>
7
- handlers.handle(
8
- "location.get",
9
- Effect.fn(function* () {
10
- const location = yield* Location.Service
11
- return new Location.Info({
12
- directory: location.directory,
13
- workspaceID: location.workspaceID,
14
- project: location.project,
15
- })
16
- }),
17
- ),
18
- )
@@ -1,81 +0,0 @@
1
- import { SessionMessage } from "@zyraxon-ai/core/session/message"
2
- import { SessionV2 } from "@zyraxon-ai/core/session"
3
- import { Effect, Schema } from "effect"
4
- import { HttpApiBuilder } from "effect/unstable/httpapi"
5
- import { Api } from "../api"
6
- import { InvalidCursorError, SessionNotFoundError, UnknownError } from "@zyraxon-ai/protocol/errors"
7
-
8
- const DefaultMessagesLimit = 50
9
-
10
- const Cursor = Schema.Struct({
11
- id: SessionMessage.ID,
12
- order: Schema.Union([Schema.Literal("asc"), Schema.Literal("desc")]),
13
- direction: Schema.Union([Schema.Literal("previous"), Schema.Literal("next")]),
14
- })
15
-
16
- const decodeCursor = Schema.decodeUnknownSync(Cursor)
17
-
18
- const cursor = {
19
- encode(message: SessionMessage.Message, order: "asc" | "desc", direction: "previous" | "next") {
20
- return Buffer.from(JSON.stringify({ id: message.id, order, direction })).toString("base64url")
21
- },
22
- decode(input: string) {
23
- return decodeCursor(JSON.parse(Buffer.from(input, "base64url").toString("utf8")))
24
- },
25
- }
26
-
27
- export const MessageHandler = HttpApiBuilder.group(Api, "server.message", (handlers) =>
28
- Effect.gen(function* () {
29
- const session = yield* SessionV2.Service
30
-
31
- return handlers.handle(
32
- "session.messages",
33
- Effect.fn(function* (ctx) {
34
- if (ctx.query.cursor && ctx.query.order !== undefined)
35
- return yield* new InvalidCursorError({ message: "Cursor cannot be combined with order" })
36
- const decoded = yield* Effect.try({
37
- try: () => (ctx.query.cursor ? cursor.decode(ctx.query.cursor) : undefined),
38
- catch: () => new InvalidCursorError({ message: "Invalid cursor" }),
39
- })
40
- const order = decoded?.order ?? ctx.query.order ?? "desc"
41
- const messages = yield* session
42
- .messages({
43
- sessionID: ctx.params.sessionID,
44
- limit: ctx.query.limit ?? DefaultMessagesLimit,
45
- order,
46
- cursor: decoded ? { id: decoded.id, direction: decoded.direction } : undefined,
47
- })
48
- .pipe(
49
- Effect.catchTag("Session.NotFoundError", (error) =>
50
- Effect.fail(
51
- new SessionNotFoundError({
52
- sessionID: error.sessionID,
53
- message: `Session not found: ${error.sessionID}`,
54
- }),
55
- ),
56
- ),
57
- Effect.catchTag("Session.MessageDecodeError", (error) => {
58
- const ref = `err_${crypto.randomUUID().slice(0, 8)}`
59
- return Effect.logError("failed to decode session message").pipe(
60
- Effect.annotateLogs({ ref, sessionID: error.sessionID, messageID: error.messageID }),
61
- Effect.andThen(
62
- Effect.fail(
63
- new UnknownError({ message: "Unexpected server error. Check server logs for details.", ref }),
64
- ),
65
- ),
66
- )
67
- }),
68
- )
69
- const first = messages[0]
70
- const last = messages.at(-1)
71
- return {
72
- data: messages,
73
- cursor: {
74
- previous: first ? cursor.encode(first, order, "previous") : undefined,
75
- next: last ? cursor.encode(last, order, "next") : undefined,
76
- },
77
- }
78
- }),
79
- )
80
- }),
81
- )
@@ -1,17 +0,0 @@
1
- import { Catalog } from "@zyraxon-ai/core/catalog"
2
- import { Effect } from "effect"
3
- import { HttpApiBuilder } from "effect/unstable/httpapi"
4
- import { Api } from "../api"
5
- import { response } from "../location"
6
-
7
- export const ModelHandler = HttpApiBuilder.group(Api, "server.model", (handlers) =>
8
- Effect.gen(function* () {
9
- return handlers.handle(
10
- "model.list",
11
- Effect.fn(function* () {
12
- const catalog = yield* Catalog.Service
13
- return yield* response(catalog.model.available())
14
- }),
15
- )
16
- }),
17
- )
@@ -1,98 +0,0 @@
1
- import { Location } from "@zyraxon-ai/core/location"
2
- import { PermissionV2 } from "@zyraxon-ai/core/permission"
3
- import { PermissionSaved } from "@zyraxon-ai/core/permission/saved"
4
- import { Effect } from "effect"
5
- import { HttpApiBuilder, HttpApiSchema } from "effect/unstable/httpapi"
6
- import { Api } from "../api"
7
- import { PermissionNotFoundError, SessionNotFoundError } from "@zyraxon-ai/protocol/errors"
8
- import { response } from "../location"
9
-
10
- function missingRequest(id: PermissionV2.ID) {
11
- return new PermissionNotFoundError({ requestID: id, message: `Permission request not found: ${id}` })
12
- }
13
-
14
- export const PermissionHandler = HttpApiBuilder.group(Api, "server.permission", (handlers) =>
15
- Effect.gen(function* () {
16
- return handlers
17
- .handle(
18
- "permission.request.list",
19
- Effect.fn(function* () {
20
- return yield* response((yield* PermissionV2.Service).list())
21
- }),
22
- )
23
- .handle(
24
- "session.permission.create",
25
- Effect.fn(function* (ctx) {
26
- const permission = yield* PermissionV2.Service
27
- return {
28
- data: yield* permission
29
- .ask({
30
- id: ctx.payload.id,
31
- sessionID: ctx.params.sessionID,
32
- action: ctx.payload.action,
33
- resources: ctx.payload.resources,
34
- save: ctx.payload.save,
35
- metadata: ctx.payload.metadata,
36
- source: ctx.payload.source,
37
- agent: ctx.payload.agent,
38
- })
39
- .pipe(
40
- Effect.catchTag(
41
- "Session.NotFoundError",
42
- (error) =>
43
- new SessionNotFoundError({
44
- sessionID: error.sessionID,
45
- message: `Session not found: ${error.sessionID}`,
46
- }),
47
- ),
48
- ),
49
- }
50
- }),
51
- )
52
- .handle(
53
- "session.permission.list",
54
- Effect.fn(function* (ctx) {
55
- const permission = yield* PermissionV2.Service
56
- return { data: yield* permission.forSession(ctx.params.sessionID) }
57
- }),
58
- )
59
- .handle(
60
- "session.permission.get",
61
- Effect.fn(function* (ctx) {
62
- const request = yield* (yield* PermissionV2.Service).get(ctx.params.requestID)
63
- if (!request || request.sessionID !== ctx.params.sessionID) return yield* missingRequest(ctx.params.requestID)
64
- return { data: request }
65
- }),
66
- )
67
- .handle(
68
- "session.permission.reply",
69
- Effect.fn(function* (ctx) {
70
- const permission = yield* PermissionV2.Service
71
- const request = yield* permission.get(ctx.params.requestID)
72
- if (!request || request.sessionID !== ctx.params.sessionID) return yield* missingRequest(ctx.params.requestID)
73
- yield* permission
74
- .reply({ requestID: ctx.params.requestID, reply: ctx.payload.reply, message: ctx.payload.message })
75
- .pipe(Effect.catchTag("PermissionV2.NotFoundError", () => missingRequest(ctx.params.requestID)))
76
- return HttpApiSchema.NoContent.make()
77
- }),
78
- )
79
- .handle(
80
- "permission.saved.list",
81
- Effect.fn(function* (ctx) {
82
- const location = yield* Location.Service
83
- return {
84
- data: yield* (yield* PermissionSaved.Service).list({
85
- projectID: ctx.query.projectID ?? location.project.id,
86
- }),
87
- }
88
- }),
89
- )
90
- .handle(
91
- "permission.saved.remove",
92
- Effect.fn(function* (ctx) {
93
- yield* (yield* PermissionSaved.Service).remove(ctx.params.id)
94
- return HttpApiSchema.NoContent.make()
95
- }),
96
- )
97
- }),
98
- )
@@ -1,68 +0,0 @@
1
- import { Location } from "@zyraxon-ai/core/location"
2
- import { ProjectCopy } from "@zyraxon-ai/core/project/copy"
3
- import { Git } from "@zyraxon-ai/core/git"
4
- import { Effect } from "effect"
5
- import { HttpApiBuilder, HttpApiSchema } from "effect/unstable/httpapi"
6
- import { Api } from "../api"
7
- import { ProjectCopyError } from "@zyraxon-ai/protocol/groups/project-copy"
8
-
9
- export const ProjectCopyHandler = HttpApiBuilder.group(Api, "server.projectCopy", (handlers) =>
10
- Effect.succeed(
11
- handlers
12
- .handle("projectCopy.create", (ctx) =>
13
- Effect.gen(function* () {
14
- const copies = yield* ProjectCopy.Service
15
- const location = yield* Location.Service
16
- return yield* badRequest(
17
- copies.create({
18
- ...ctx.payload,
19
- projectID: ctx.params.projectID,
20
- sourceDirectory: location.project.directory,
21
- }),
22
- )
23
- }),
24
- )
25
- .handle("projectCopy.remove", (ctx) =>
26
- ProjectCopy.Service.use((copies) =>
27
- badRequest(copies.remove({ ...ctx.payload, projectID: ctx.params.projectID })).pipe(
28
- Effect.as(HttpApiSchema.NoContent.make()),
29
- ),
30
- ),
31
- )
32
- .handle("projectCopy.refresh", (ctx) =>
33
- ProjectCopy.Service.use((copies) =>
34
- badRequest(copies.refresh({ projectID: ctx.params.projectID })).pipe(
35
- Effect.as(HttpApiSchema.NoContent.make()),
36
- ),
37
- ),
38
- ),
39
- ),
40
- )
41
-
42
- function badRequest<A, R>(effect: Effect.Effect<A, ProjectCopy.Error, R>) {
43
- return effect.pipe(
44
- Effect.mapError(
45
- (error) =>
46
- new ProjectCopyError({
47
- name: "ProjectCopyError",
48
- data: {
49
- message: message(error),
50
- forceRequired: error instanceof Git.WorktreeError ? error.forceRequired : undefined,
51
- },
52
- }),
53
- ),
54
- )
55
- }
56
-
57
- function message(error: ProjectCopy.Error) {
58
- if (error instanceof ProjectCopy.SourceDirectoryNotFoundError)
59
- return `Project copy source not found: ${error.directory}`
60
- if (error instanceof ProjectCopy.DestinationExistsError)
61
- return `Project copy destination already exists: ${error.directory}`
62
- if (error instanceof ProjectCopy.DirectoryUnavailableError)
63
- return `Project copy directory unavailable: ${error.directory}`
64
- if (error instanceof ProjectCopy.InvalidDirectoryError) return `Invalid project copy directory: ${error.directory}`
65
- if (error instanceof ProjectCopy.StrategyUnavailableError)
66
- return `Project copy strategy unavailable: ${error.strategy}`
67
- return error.message
68
- }
@@ -1,32 +0,0 @@
1
- import { Catalog } from "@zyraxon-ai/core/catalog"
2
- import { Effect } from "effect"
3
- import { HttpApiBuilder } from "effect/unstable/httpapi"
4
- import { Api } from "../api"
5
- import { ProviderNotFoundError } from "@zyraxon-ai/protocol/errors"
6
- import { response } from "../location"
7
-
8
- export const ProviderHandler = HttpApiBuilder.group(Api, "server.provider", (handlers) =>
9
- Effect.gen(function* () {
10
- return handlers
11
- .handle(
12
- "provider.list",
13
- Effect.fn(function* () {
14
- const catalog = yield* Catalog.Service
15
- return yield* response(catalog.provider.all())
16
- }),
17
- )
18
- .handle(
19
- "provider.get",
20
- Effect.fn(function* (ctx) {
21
- const catalog = yield* Catalog.Service
22
- const provider = yield* catalog.provider.get(ctx.params.providerID)
23
- if (!provider)
24
- return yield* new ProviderNotFoundError({
25
- providerID: ctx.params.providerID,
26
- message: `Provider not found: ${ctx.params.providerID}`,
27
- })
28
- return yield* response(Effect.succeed(provider))
29
- }),
30
- )
31
- }),
32
- )