@krak-stack/registry 0.1.11 → 0.1.14

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 (51) hide show
  1. package/README.md +31 -2
  2. package/dist/components/ui/app-brand.d.ts +18 -13
  3. package/dist/components/ui/app-brand.js +48 -15
  4. package/dist/components/ui/code-block.js +10 -6
  5. package/dist/components/ui/copy-button.d.ts +1 -1
  6. package/dist/components/ui/copy-button.js +1 -1
  7. package/dist/components/ui/data-table.d.ts +1 -1
  8. package/dist/components/ui/data-table.js +21 -20
  9. package/dist/components/ui/effect-form.js +7 -6
  10. package/dist/components/ui/file-picker.js +2 -1
  11. package/dist/components/ui/form.js +17 -15
  12. package/dist/components/ui/google-map.d.ts +6 -10
  13. package/dist/components/ui/google-map.js +19 -14
  14. package/dist/components/ui/locale-switcher.js +7 -1
  15. package/dist/components/ui/sidebar-layout.js +19 -21
  16. package/dist/components/ui/theme-switcher.js +1 -1
  17. package/dist/lib/docs-core.js +165 -109
  18. package/dist/lib/documentation-toolkit.d.ts +140 -0
  19. package/dist/lib/{docs-ai.js → documentation-toolkit.js} +54 -63
  20. package/dist/lib/httpapi-cli.d.ts +6 -6
  21. package/dist/lib/httpapi-cli.js +75 -48
  22. package/dist/lib/httpapi-client.d.ts +8 -2
  23. package/dist/lib/httpapi-client.js +21 -9
  24. package/dist/lib/httpapi-helpers.d.ts +15 -21
  25. package/dist/lib/httpapi-helpers.js +38 -26
  26. package/dist/lib/httpapi-mcp.js +73 -50
  27. package/dist/lib/httpapi-toolkit.d.ts +20 -0
  28. package/dist/lib/{httpapi-ai.js → httpapi-toolkit.js} +123 -100
  29. package/dist/lib/seo.js +29 -17
  30. package/dist/lib/webfetch-toolkit.d.ts +45 -0
  31. package/dist/lib/webfetch-toolkit.js +276 -0
  32. package/dist/oxlint/anti-slop/index.js +1592 -0
  33. package/dist/services/agent/client/atom.d.ts +7 -7
  34. package/dist/services/agent/client/index.js +55 -54
  35. package/dist/services/agent/index.d.ts +71 -71
  36. package/dist/services/agent/index.js +38 -19
  37. package/dist/services/notification/channels/index.d.ts +11 -9
  38. package/dist/services/notification/channels/ses/index.d.ts +6 -6
  39. package/dist/services/notification/channels/ses/index.js +15 -11
  40. package/dist/services/notification/client/index.js +3 -2
  41. package/dist/services/notification/client/notification-menu.d.ts +9 -9
  42. package/dist/services/notification/index.d.ts +7 -6
  43. package/dist/services/notification/persistence/drizzle.js +214 -0
  44. package/dist/services/notification/persistence/index.js +227 -0
  45. package/dist/services/notification/persistence/schema.js +118 -0
  46. package/dist/services/notification/public.js +3 -2
  47. package/dist/services/s3/index.d.ts +2 -16
  48. package/dist/services/s3/index.js +12 -9
  49. package/package.json +33 -7
  50. package/dist/lib/docs-ai.d.ts +0 -142
  51. package/dist/lib/httpapi-ai.d.ts +0 -54
@@ -1,7 +1,9 @@
1
1
  import { Context, Effect, JsonSchema, Layer, Schema } from "effect";
2
+ import type { Json } from "effect/Schema";
2
3
  import { HttpApi, OpenApi } from "effect/unstable/httpapi";
3
- export declare const JsonObjectSchema: Schema.$Record<Schema.String, Schema.Unknown>;
4
+ export declare const JsonObjectSchema: Schema.$Record<Schema.String, Schema.Codec<Json, Json, never, never>>;
4
5
  export type JsonObject = typeof JsonObjectSchema.Type;
6
+ type HttpBoundaryError = ErrorOptions["cause"];
5
7
  export type HttpApiDocument = ReturnType<typeof OpenApi.fromApi>;
6
8
  export type HttpApiMethod = "get" | "post" | "put" | "patch" | "delete";
7
9
  export declare const HttpApiMethods: ReadonlyArray<HttpApiMethod>;
@@ -31,7 +33,7 @@ export type HttpApiOperationEntry = {
31
33
  readonly operation: HttpApiOperation;
32
34
  };
33
35
  export type HttpApiOperationInput = {
34
- readonly body?: unknown;
36
+ readonly body?: Json;
35
37
  readonly headers: JsonObject;
36
38
  readonly params: JsonObject;
37
39
  readonly query: JsonObject;
@@ -41,7 +43,7 @@ export type HttpApiSpecConfig = {
41
43
  readonly methods?: ReadonlyArray<HttpApiMethod>;
42
44
  readonly include?: (operation: HttpApiOperationEntry) => boolean;
43
45
  };
44
- export declare const toHttpError: (message: string, error: unknown) => Error;
46
+ export declare const toHttpError: (message: string, error: HttpBoundaryError) => Error;
45
47
  export declare const sanitizeHttpName: (name: string) => string;
46
48
  export declare const httpApiToolName: (method: string, path: string, operation: HttpApiOperation) => string;
47
49
  export declare const httpApiOperations: ({ spec, methods, }: {
@@ -55,46 +57,38 @@ export declare const httpApiToolEntries: (operations: readonly HttpApiOperationE
55
57
  name: string;
56
58
  }[], Error, never>;
57
59
  export declare const httpApiOperationInputSchema: (operation: HttpApiOperation) => JsonSchema.JsonSchema;
58
- export declare const decodeHttpApiOperationInput: (input: unknown, operation: HttpApiOperation) => Effect.Effect<{
59
- body?: unknown;
60
+ export declare const decodeHttpApiOperationInput: (input: Json, operation: HttpApiOperation) => Effect.Effect<{
61
+ body?: Json | undefined;
60
62
  headers: any;
61
63
  params: any;
62
64
  query: any;
63
65
  }, Error, never>;
64
66
  export declare const parseJsonObject: (value: string | undefined, label: string) => Effect.Effect<{
65
- readonly [x: string]: unknown;
67
+ readonly [x: string]: Json;
66
68
  }, Error, never>;
67
- export declare const parseJsonValue: (value: string | undefined, label: string) => Effect.Effect<unknown, Error, never>;
69
+ export declare const parseJsonValue: (value: string | undefined, label: string) => Effect.Effect<Json | undefined, Error, never>;
68
70
  declare const HttpApiSpec_base: Context.ServiceClass<HttpApiSpec, "HttpApiSpec", {
69
71
  info: OpenApi.OpenAPISpecInfo;
70
72
  operations: HttpApiOperationEntry[];
71
- decodeOperationInput: (input: unknown, operation: HttpApiOperation) => Effect.Effect<{
72
- body?: unknown;
73
+ decodeOperationInput: (input: Json, operation: HttpApiOperation) => Effect.Effect<{
74
+ body?: Json | undefined;
73
75
  headers: any;
74
76
  params: any;
75
77
  query: any;
76
78
  }, Error, never>;
77
- operationJsonSchema: (operation: HttpApiOperation) => {
78
- $defs?: {
79
- [k: string]: JsonSchema.JsonSchema;
80
- } | undefined;
81
- };
79
+ operationJsonSchema: (operation: HttpApiOperation) => JsonSchema.JsonSchema;
82
80
  operationSchema: (operation: HttpApiOperation) => Schema.Top;
83
81
  }> & {
84
82
  readonly make: (config: HttpApiSpecConfig) => Effect.Effect<{
85
83
  info: OpenApi.OpenAPISpecInfo;
86
84
  operations: HttpApiOperationEntry[];
87
- decodeOperationInput: (input: unknown, operation: HttpApiOperation) => Effect.Effect<{
88
- body?: unknown;
85
+ decodeOperationInput: (input: Json, operation: HttpApiOperation) => Effect.Effect<{
86
+ body?: Json | undefined;
89
87
  headers: any;
90
88
  params: any;
91
89
  query: any;
92
90
  }, Error, never>;
93
- operationJsonSchema: (operation: HttpApiOperation) => {
94
- $defs?: {
95
- [k: string]: JsonSchema.JsonSchema;
96
- } | undefined;
97
- };
91
+ operationJsonSchema: (operation: HttpApiOperation) => JsonSchema.JsonSchema;
98
92
  operationSchema: (operation: HttpApiOperation) => Schema.Top;
99
93
  }, Error, never>;
100
94
  };
@@ -9,25 +9,25 @@ import {
9
9
  SchemaRepresentation
10
10
  } from "effect";
11
11
  import { HttpApi, OpenApi } from "effect/unstable/httpapi";
12
- var JsonObjectSchema = Schema.Record(Schema.String, Schema.Unknown).annotate({
12
+ var JsonObjectSchema = Schema.Record(Schema.String, Schema.Json).annotate({
13
13
  identifier: "HttpJsonObject",
14
14
  title: "HTTP JSON object",
15
15
  description: "A JSON object passed to an HTTP API operation.",
16
16
  examples: [{ id: "example-id" }]
17
17
  });
18
18
  var JsonObjectFromString = Schema.fromJsonString(JsonObjectSchema);
19
- var JsonValueFromString = Schema.fromJsonString(Schema.Unknown);
19
+ var JsonValueFromString = Schema.fromJsonString(Schema.Json);
20
20
  var JsonSchemaAnnotations = Schema.Struct({
21
21
  title: Schema.optional(Schema.String),
22
22
  description: Schema.optional(Schema.String),
23
- examples: Schema.optional(Schema.Array(Schema.Unknown))
23
+ examples: Schema.optional(Schema.Array(Schema.Json))
24
24
  }).annotate({
25
25
  identifier: "HttpJsonSchemaAnnotations",
26
26
  title: "HTTP JSON Schema annotations",
27
27
  description: "JSON Schema annotations surfaced on generated tool inputs."
28
28
  });
29
29
  var HttpApiToolInputSchema = Schema.Struct({
30
- body: Schema.optional(Schema.Unknown)
30
+ body: Schema.optional(Schema.Json)
31
31
  }).annotate({
32
32
  identifier: "HttpApiToolInput",
33
33
  title: "HTTP API tool input",
@@ -41,6 +41,8 @@ var HttpApiMethods = [
41
41
  "patch",
42
42
  "delete"
43
43
  ];
44
+ var HttpApiOperationSchema = Schema.declare((value) => Schema.is(JsonObjectSchema)(value)).annotate({ identifier: "HttpApiOperation" });
45
+ var decodeHttpApiOperation = Schema.decodeUnknownOption(HttpApiOperationSchema);
44
46
  var toHttpError = (message, error) => new Error(message, { cause: error });
45
47
  var sanitizeHttpName = (name) => name.replace(/[^a-zA-Z0-9_-]/g, "_").replace(/_+/g, "_").replace(/^_+|_+$/g, "");
46
48
  var httpApiToolName = (method, path, operation) => {
@@ -54,9 +56,10 @@ var httpApiOperations = ({
54
56
  const operations = [];
55
57
  for (const [path, pathItem] of Object.entries(spec.paths)) {
56
58
  for (const method of methods) {
57
- const operation = pathItem[method];
58
- if (operation)
59
- operations.push({ method, path, operation });
59
+ const operation = decodeHttpApiOperation(pathItem[method]);
60
+ if (Option.isSome(operation)) {
61
+ operations.push({ method, path, operation: operation.value });
62
+ }
60
63
  }
61
64
  }
62
65
  return operations;
@@ -85,30 +88,36 @@ var schemaWithVisibleAnnotations = (schema) => {
85
88
  ...acc,
86
89
  ...decodeAnnotations(item).pipe(Option.getOrElse(() => ({})))
87
90
  }), directAnnotations);
88
- return {
89
- ...schema,
90
- ..."title" in annotations && !("title" in schema) ? { title: annotations.title } : {},
91
- ..."description" in annotations && !("description" in schema) ? { description: annotations.description } : {},
92
- ..."examples" in annotations && !("examples" in schema) ? { examples: annotations.examples } : {}
93
- };
91
+ const visible = { ...schema };
92
+ if ("title" in annotations && !("title" in schema)) {
93
+ visible.title = annotations.title;
94
+ }
95
+ if ("description" in annotations && !("description" in schema)) {
96
+ visible.description = annotations.description;
97
+ }
98
+ if ("examples" in annotations && !("examples" in schema)) {
99
+ visible.examples = annotations.examples;
100
+ }
101
+ return visible;
94
102
  };
95
103
  var referencedDefinitions = (schema, definitions) => {
96
104
  const names = new Set;
97
- const pending = [schema];
105
+ const pending = [Schema.decodeUnknownSync(Schema.Json)(schema)];
98
106
  while (pending.length > 0) {
99
107
  const current = pending.pop();
100
- if (!current || typeof current !== "object")
101
- continue;
102
108
  if (Array.isArray(current)) {
103
109
  pending.push(...current);
104
110
  continue;
105
111
  }
106
- for (const [key, value] of Object.entries(current)) {
107
- if (key === "$ref" && typeof value === "string") {
112
+ const record = Schema.decodeUnknownOption(Schema.Record(Schema.String, Schema.Json))(current);
113
+ if (Option.isNone(record))
114
+ continue;
115
+ for (const [key, value] of Object.entries(record.value)) {
116
+ if (key === "$ref" && Schema.is(Schema.String)(value)) {
108
117
  const name = value.match(/^#\/(?:\$defs|components\/schemas)\/(.+)$/)?.[1];
109
118
  if (name && !names.has(name) && definitions[name]) {
110
119
  names.add(name);
111
- pending.push(definitions[name]);
120
+ pending.push(Schema.decodeUnknownSync(Schema.Json)(definitions[name]));
112
121
  }
113
122
  } else if (key !== "$defs") {
114
123
  pending.push(value);
@@ -131,10 +140,12 @@ var httpApiOperationInputSchema = (operation) => {
131
140
  ...queryParameters,
132
141
  ...headerParameters
133
142
  ]) {
134
- properties[parameter.name] = {
135
- ...parameter.schema ? schemaWithVisibleAnnotations(parameter.schema) : { type: "string" },
136
- ...parameter.description ? { description: parameter.description } : {}
143
+ const property = {
144
+ ...parameter.schema ? schemaWithVisibleAnnotations(parameter.schema) : { type: "string" }
137
145
  };
146
+ if (parameter.description)
147
+ property.description = parameter.description;
148
+ properties[parameter.name] = property;
138
149
  if (parameter.required)
139
150
  required.push(parameter.name);
140
151
  }
@@ -200,10 +211,11 @@ class HttpApiSpec extends Context.Service()("HttpApiSpec", {
200
211
  });
201
212
  const definitions = document.definitions ?? {};
202
213
  const usedDefinitions = referencedDefinitions(document.schema, definitions);
203
- return {
204
- ...document.schema,
205
- ...Object.keys(usedDefinitions).length > 0 ? { $defs: usedDefinitions } : {}
206
- };
214
+ const result = { ...document.schema };
215
+ if (Object.keys(usedDefinitions).length > 0) {
216
+ result.$defs = usedDefinitions;
217
+ }
218
+ return result;
207
219
  };
208
220
  return {
209
221
  info: spec.info,
@@ -1,18 +1,26 @@
1
1
  // ../../src/lib/httpapi-mcp.ts
2
- import { Context as Context3, Effect as Effect3, Layer as Layer3, Option as Option2, Schema as Schema2 } from "effect";
2
+ import { Context as Context3, Effect as Effect3, Layer as Layer3, Option as Option2, Schema as Schema3 } from "effect";
3
3
  import { McpSchema, McpServer } from "effect/unstable/ai";
4
4
 
5
5
  // ../../src/lib/httpapi-client.ts
6
- import { Context, Effect, Layer } from "effect";
6
+ import { Context, Effect, Layer, Schema } from "effect";
7
7
  import { HttpClient } from "effect/unstable/http";
8
8
  import {
9
9
  HttpApiClient as EffectHttpApiClient
10
10
  } from "effect/unstable/httpapi";
11
+ var HttpApiOperationResult = Schema.Union([
12
+ Schema.Json,
13
+ Schema.DateFromString,
14
+ Schema.Uint8ArrayFromBase64,
15
+ Schema.Undefined
16
+ ]).annotate({ identifier: "HttpApiOperationResult" });
17
+ var encodeHttpApiOperationResult = Effect.fn("HttpApiClient.encodeOperationResult")((result) => Schema.encodeUnknownEffect(HttpApiOperationResult)(result).pipe(Effect.map((encoded) => encoded ?? null), Effect.mapError((cause) => new Error("HTTP API result is not serializable", { cause }))));
18
+ var GeneratedOperation = Schema.declare((value) => value instanceof Function).annotate({ identifier: "GeneratedOperation" });
19
+ var GeneratedOperationEffect = Schema.declare((value) => Effect.isEffect(value)).annotate({ identifier: "GeneratedOperationEffect" });
11
20
  var makeGeneratedClient = (api, http, baseUrl) => EffectHttpApiClient.makeWith(api, {
12
21
  baseUrl,
13
22
  httpClient: http
14
23
  });
15
- var isClientEffect = (value) => Effect.isEffect(value);
16
24
  var executeGeneratedOperation = Effect.fn("HttpApiClient.executeGeneratedOperation")(function* (client, { input, operation: entry }) {
17
25
  const operationId = entry.operation.operationId;
18
26
  if (!operationId) {
@@ -20,22 +28,23 @@ var executeGeneratedOperation = Effect.fn("HttpApiClient.executeGeneratedOperati
20
28
  }
21
29
  const target = Object(client);
22
30
  const groupName = Object.keys(target).filter((name) => operationId.startsWith(`${name}.`)).sort((a, b) => b.length - a.length)[0];
23
- const group = groupName ? Reflect.get(target, groupName) : target;
31
+ const group = groupName ? Object.entries(target).find(([name]) => name === groupName)?.[1] : target;
24
32
  const endpointName = groupName ? operationId.slice(groupName.length + 1) : operationId;
25
- const endpoint = Reflect.get(Object(group), endpointName);
26
- if (typeof endpoint !== "function") {
33
+ const endpointCandidate = group instanceof Function ? undefined : Object.entries(Object(group)).find(([name]) => name === endpointName)?.[1];
34
+ const endpoint = Schema.decodeUnknownOption(GeneratedOperation)(endpointCandidate);
35
+ if (endpoint._tag === "None") {
27
36
  return yield* Effect.fail(new Error(`No generated API client operation for ${operationId}`));
28
37
  }
29
- const result = endpoint({
38
+ const result = Schema.decodeUnknownOption(GeneratedOperationEffect)(endpoint.value({
30
39
  headers: input.headers,
31
40
  params: input.params,
32
41
  query: input.query,
33
42
  payload: input.body
34
- });
35
- if (!isClientEffect(result)) {
43
+ }));
44
+ if (result._tag === "None") {
36
45
  return yield* Effect.fail(new Error(`Generated API client operation ${operationId} is invalid`));
37
46
  }
38
- return yield* result;
47
+ return yield* result.value;
39
48
  });
40
49
 
41
50
  class ApiClient extends Context.Service()("ApiClient") {
@@ -43,6 +52,7 @@ class ApiClient extends Context.Service()("ApiClient") {
43
52
  const http = yield* HttpClient.HttpClient;
44
53
  const client = yield* makeGeneratedClient(config.api, http, config.baseUrl);
45
54
  return {
55
+ encodeResult: config.encodeResult ?? ((result) => encodeHttpApiOperationResult(result)),
46
56
  execute: Effect.fn("ApiClient.execute")(function* (options) {
47
57
  return yield* executeGeneratedOperation(client, options);
48
58
  })
@@ -57,29 +67,29 @@ import {
57
67
  JsonSchema,
58
68
  Layer as Layer2,
59
69
  Option,
60
- Schema,
70
+ Schema as Schema2,
61
71
  SchemaRepresentation
62
72
  } from "effect";
63
73
  import { HttpApi as HttpApi2, OpenApi } from "effect/unstable/httpapi";
64
- var JsonObjectSchema = Schema.Record(Schema.String, Schema.Unknown).annotate({
74
+ var JsonObjectSchema = Schema2.Record(Schema2.String, Schema2.Json).annotate({
65
75
  identifier: "HttpJsonObject",
66
76
  title: "HTTP JSON object",
67
77
  description: "A JSON object passed to an HTTP API operation.",
68
78
  examples: [{ id: "example-id" }]
69
79
  });
70
- var JsonObjectFromString = Schema.fromJsonString(JsonObjectSchema);
71
- var JsonValueFromString = Schema.fromJsonString(Schema.Unknown);
72
- var JsonSchemaAnnotations = Schema.Struct({
73
- title: Schema.optional(Schema.String),
74
- description: Schema.optional(Schema.String),
75
- examples: Schema.optional(Schema.Array(Schema.Unknown))
80
+ var JsonObjectFromString = Schema2.fromJsonString(JsonObjectSchema);
81
+ var JsonValueFromString = Schema2.fromJsonString(Schema2.Json);
82
+ var JsonSchemaAnnotations = Schema2.Struct({
83
+ title: Schema2.optional(Schema2.String),
84
+ description: Schema2.optional(Schema2.String),
85
+ examples: Schema2.optional(Schema2.Array(Schema2.Json))
76
86
  }).annotate({
77
87
  identifier: "HttpJsonSchemaAnnotations",
78
88
  title: "HTTP JSON Schema annotations",
79
89
  description: "JSON Schema annotations surfaced on generated tool inputs."
80
90
  });
81
- var HttpApiToolInputSchema = Schema.Struct({
82
- body: Schema.optional(Schema.Unknown)
91
+ var HttpApiToolInputSchema = Schema2.Struct({
92
+ body: Schema2.optional(Schema2.Json)
83
93
  }).annotate({
84
94
  identifier: "HttpApiToolInput",
85
95
  title: "HTTP API tool input",
@@ -93,6 +103,8 @@ var HttpApiMethods = [
93
103
  "patch",
94
104
  "delete"
95
105
  ];
106
+ var HttpApiOperationSchema = Schema2.declare((value) => Schema2.is(JsonObjectSchema)(value)).annotate({ identifier: "HttpApiOperation" });
107
+ var decodeHttpApiOperation = Schema2.decodeUnknownOption(HttpApiOperationSchema);
96
108
  var toHttpError = (message, error) => new Error(message, { cause: error });
97
109
  var httpApiToolName = (method, path, operation) => {
98
110
  const fallback = `${method}_${path.replace(/^\/api\//, "").replace(/[/:{}]/g, "_")}`;
@@ -105,9 +117,10 @@ var httpApiOperations = ({
105
117
  const operations = [];
106
118
  for (const [path, pathItem] of Object.entries(spec.paths)) {
107
119
  for (const method of methods) {
108
- const operation = pathItem[method];
109
- if (operation)
110
- operations.push({ method, path, operation });
120
+ const operation = decodeHttpApiOperation(pathItem[method]);
121
+ if (Option.isSome(operation)) {
122
+ operations.push({ method, path, operation: operation.value });
123
+ }
111
124
  }
112
125
  }
113
126
  return operations;
@@ -128,7 +141,7 @@ var httpApiToolEntries = Effect2.fn("Http.toolEntries")(function* (operations) {
128
141
  catch: (error) => error instanceof Error ? error : new Error(String(error))
129
142
  });
130
143
  });
131
- var decodeAnnotations = Schema.decodeUnknownOption(JsonSchemaAnnotations);
144
+ var decodeAnnotations = Schema2.decodeUnknownOption(JsonSchemaAnnotations);
132
145
  var schemaWithVisibleAnnotations = (schema) => {
133
146
  const directAnnotations = decodeAnnotations(schema).pipe(Option.getOrElse(() => ({})));
134
147
  const allOf = Array.isArray(schema.allOf) ? schema.allOf : [];
@@ -136,30 +149,36 @@ var schemaWithVisibleAnnotations = (schema) => {
136
149
  ...acc,
137
150
  ...decodeAnnotations(item).pipe(Option.getOrElse(() => ({})))
138
151
  }), directAnnotations);
139
- return {
140
- ...schema,
141
- ..."title" in annotations && !("title" in schema) ? { title: annotations.title } : {},
142
- ..."description" in annotations && !("description" in schema) ? { description: annotations.description } : {},
143
- ..."examples" in annotations && !("examples" in schema) ? { examples: annotations.examples } : {}
144
- };
152
+ const visible = { ...schema };
153
+ if ("title" in annotations && !("title" in schema)) {
154
+ visible.title = annotations.title;
155
+ }
156
+ if ("description" in annotations && !("description" in schema)) {
157
+ visible.description = annotations.description;
158
+ }
159
+ if ("examples" in annotations && !("examples" in schema)) {
160
+ visible.examples = annotations.examples;
161
+ }
162
+ return visible;
145
163
  };
146
164
  var referencedDefinitions = (schema, definitions) => {
147
165
  const names = new Set;
148
- const pending = [schema];
166
+ const pending = [Schema2.decodeUnknownSync(Schema2.Json)(schema)];
149
167
  while (pending.length > 0) {
150
168
  const current = pending.pop();
151
- if (!current || typeof current !== "object")
152
- continue;
153
169
  if (Array.isArray(current)) {
154
170
  pending.push(...current);
155
171
  continue;
156
172
  }
157
- for (const [key, value] of Object.entries(current)) {
158
- if (key === "$ref" && typeof value === "string") {
173
+ const record = Schema2.decodeUnknownOption(Schema2.Record(Schema2.String, Schema2.Json))(current);
174
+ if (Option.isNone(record))
175
+ continue;
176
+ for (const [key, value] of Object.entries(record.value)) {
177
+ if (key === "$ref" && Schema2.is(Schema2.String)(value)) {
159
178
  const name = value.match(/^#\/(?:\$defs|components\/schemas)\/(.+)$/)?.[1];
160
179
  if (name && !names.has(name) && definitions[name]) {
161
180
  names.add(name);
162
- pending.push(definitions[name]);
181
+ pending.push(Schema2.decodeUnknownSync(Schema2.Json)(definitions[name]));
163
182
  }
164
183
  } else if (key !== "$defs") {
165
184
  pending.push(value);
@@ -182,10 +201,12 @@ var httpApiOperationInputSchema = (operation) => {
182
201
  ...queryParameters,
183
202
  ...headerParameters
184
203
  ]) {
185
- properties[parameter.name] = {
186
- ...parameter.schema ? schemaWithVisibleAnnotations(parameter.schema) : { type: "string" },
187
- ...parameter.description ? { description: parameter.description } : {}
204
+ const property = {
205
+ ...parameter.schema ? schemaWithVisibleAnnotations(parameter.schema) : { type: "string" }
188
206
  };
207
+ if (parameter.description)
208
+ property.description = parameter.description;
209
+ properties[parameter.name] = property;
189
210
  if (parameter.required)
190
211
  required.push(parameter.name);
191
212
  }
@@ -201,10 +222,10 @@ var httpApiOperationInputSchema = (operation) => {
201
222
  additionalProperties: false
202
223
  };
203
224
  };
204
- var decodeJsonObject = Schema.decodeUnknownOption(JsonObjectSchema);
225
+ var decodeJsonObject = Schema2.decodeUnknownOption(JsonObjectSchema);
205
226
  var decodeHttpApiOperationInput = Effect2.fn("Http.decodeApiOperationInput")(function* (input, operation) {
206
- const payload = yield* Schema.decodeUnknownEffect(JsonObjectSchema)(input ?? {}).pipe(Effect2.mapError(() => new Error("Tool input must be a JSON object")));
207
- const decoded = yield* Schema.decodeUnknownEffect(HttpApiToolInputSchema)(payload).pipe(Effect2.mapError(() => new Error("Tool input must be a JSON object")));
227
+ const payload = yield* Schema2.decodeUnknownEffect(JsonObjectSchema)(input ?? {}).pipe(Effect2.mapError(() => new Error("Tool input must be a JSON object")));
228
+ const decoded = yield* Schema2.decodeUnknownEffect(HttpApiToolInputSchema)(payload).pipe(Effect2.mapError(() => new Error("Tool input must be a JSON object")));
208
229
  const parameters = operation.parameters ?? [];
209
230
  const pickParameters = (location) => {
210
231
  const nestedKey = location === "path" ? "params" : location;
@@ -224,12 +245,12 @@ var decodeHttpApiOperationInput = Effect2.fn("Http.decodeApiOperationInput")(fun
224
245
  var parseJsonObject = Effect2.fn("Http.parseJsonObject")(function* (value, label) {
225
246
  if (!value)
226
247
  return {};
227
- return yield* Schema.decodeUnknownEffect(JsonObjectFromString)(value).pipe(Effect2.mapError(() => new Error(`${label} must be a JSON object`)));
248
+ return yield* Schema2.decodeUnknownEffect(JsonObjectFromString)(value).pipe(Effect2.mapError(() => new Error(`${label} must be a JSON object`)));
228
249
  });
229
250
  var parseJsonValue = Effect2.fn("Http.parseJsonValue")(function* (value, label) {
230
251
  if (!value)
231
252
  return;
232
- return yield* Schema.decodeUnknownEffect(JsonValueFromString)(value).pipe(Effect2.mapError(() => new Error(`${label} must be valid JSON`)));
253
+ return yield* Schema2.decodeUnknownEffect(JsonValueFromString)(value).pipe(Effect2.mapError(() => new Error(`${label} must be valid JSON`)));
233
254
  });
234
255
 
235
256
  class HttpApiSpec extends Context2.Service()("HttpApiSpec", {
@@ -251,10 +272,11 @@ class HttpApiSpec extends Context2.Service()("HttpApiSpec", {
251
272
  });
252
273
  const definitions = document.definitions ?? {};
253
274
  const usedDefinitions = referencedDefinitions(document.schema, definitions);
254
- return {
255
- ...document.schema,
256
- ...Object.keys(usedDefinitions).length > 0 ? { $defs: usedDefinitions } : {}
257
- };
275
+ const result = { ...document.schema };
276
+ if (Object.keys(usedDefinitions).length > 0) {
277
+ result.$defs = usedDefinitions;
278
+ }
279
+ return result;
258
280
  };
259
281
  return {
260
282
  info: spec.info,
@@ -285,7 +307,7 @@ class HttpApiMcp extends Context3.Service()("HttpApiMcp", {
285
307
  }) {
286
308
  static layer = (config) => Layer3.effect(this, this.make(config));
287
309
  }
288
- var decodeStructuredContent = Schema2.decodeUnknownOption(JsonObjectSchema);
310
+ var decodeStructuredContent = Schema3.decodeUnknownOption(JsonObjectSchema);
289
311
  var structuredContent = (value) => decodeStructuredContent(value).pipe(Option2.getOrElse(() => ({ result: value ?? null })));
290
312
  var toolResult = (value) => new McpSchema.CallToolResult({
291
313
  isError: false,
@@ -303,7 +325,7 @@ var toolError = (error) => new McpSchema.CallToolResult({
303
325
  });
304
326
  var executeOperation = Effect3.fn("HttpApiMcp.executeOperation")(function* (method, path, operation, input, spec, client) {
305
327
  const payload = yield* spec.decodeOperationInput(input, operation);
306
- return yield* client.execute({
328
+ const result = yield* client.execute({
307
329
  operation: { method, path, operation },
308
330
  input: {
309
331
  body: payload.body,
@@ -312,6 +334,7 @@ var executeOperation = Effect3.fn("HttpApiMcp.executeOperation")(function* (meth
312
334
  query: payload.query
313
335
  }
314
336
  });
337
+ return yield* client.encodeResult(result, { method, path, operation });
315
338
  });
316
339
  var registerOperation = (method, path, operation, name, config, spec, client) => Effect3.gen(function* () {
317
340
  const server = yield* McpServer.McpServer;
@@ -0,0 +1,20 @@
1
+ import { Effect, JsonSchema, Layer, Schema } from "effect";
2
+ import type { Json } from "effect/Schema";
3
+ import { Tool, Toolkit } from "effect/unstable/ai";
4
+ import { ApiClient } from "./httpapi-client.js";
5
+ import { HttpApiSpec, type HttpApiOperationEntry } from "./httpapi-helpers.js";
6
+ export type HttpApiToolkitConfig = {
7
+ readonly needsApproval?: (operation: HttpApiOperationEntry) => boolean;
8
+ readonly strict?: (operation: HttpApiOperationEntry) => boolean;
9
+ readonly transformResult?: (operation: HttpApiOperationEntry, result: Json) => Json;
10
+ };
11
+ export declare const makeOpenAiStrictJsonSchema: (schema: JsonSchema.JsonSchema) => JsonSchema.JsonSchema;
12
+ export declare const HttpApiToolkit: (config: HttpApiToolkitConfig) => Effect.Effect<Toolkit.Toolkit<{
13
+ readonly [x: string]: Tool.Tool<string, {
14
+ readonly parameters: Schema.Struct<{}>;
15
+ readonly success: Schema.Codec<Json, Json, never, never>;
16
+ readonly failure: Schema.String;
17
+ readonly failureMode: "return";
18
+ }, never>;
19
+ }>, Error, HttpApiSpec>;
20
+ export declare const HttpApiToolkitLayer: (config: HttpApiToolkitConfig) => Layer.Layer<Tool.Handler<string>, Error, ApiClient | HttpApiSpec>;