apps 0.0.1-beta.4 → 0.0.1-beta.41

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 (171) hide show
  1. package/README.md +68 -44
  2. package/framework-reference.json +1 -1
  3. package/js/{chunk-QKHR7BMF.js → chunk-3MMG2H6M.js} +89 -53
  4. package/js/{chunk-EQB7JMAL.js → chunk-6XGB4BAL.js} +146 -31
  5. package/js/chunk-ADD6H64X.js +729 -0
  6. package/js/{chunk-6VRYO2BG.js → chunk-AHGGO2VY.js} +837 -254
  7. package/js/{chunk-FDNTX5QJ.js → chunk-CQD3WSYH.js} +2 -2
  8. package/js/{chunk-EVJUVWN2.js → chunk-DKUEYTYD.js} +463 -218
  9. package/js/chunk-EM4UL26F.js +118 -0
  10. package/js/{chunk-2VPJHFOU.js → chunk-FXWRE655.js} +128 -24
  11. package/js/{chunk-5MQZEB6Y.js → chunk-JI3EP2GL.js} +40 -12
  12. package/js/chunk-JJSLEJ6T.js +156 -0
  13. package/js/chunk-KAQD3DTI.js +16 -0
  14. package/js/chunk-KIM5HXNK.js +49 -0
  15. package/js/chunk-MJZYV7IO.js +255 -0
  16. package/js/{chunk-FW5HBOIK.js → chunk-MXDKXAY4.js} +19117 -18309
  17. package/js/{chunk-T2LAZCAD.js → chunk-NKWWPJYX.js} +3 -3
  18. package/js/chunk-OD3KFKZD.js +1617 -0
  19. package/js/{chunk-3M2MEDNL.js → chunk-OTCLXFLL.js} +1337 -188
  20. package/js/chunk-P7MGDPFD.js +240 -0
  21. package/js/{chunk-ZCAMUXSG.js → chunk-PNVCCB4L.js} +432 -79
  22. package/js/{chunk-D47C7KG5.js → chunk-RIXVGVA6.js} +2 -2
  23. package/js/{chunk-NQ3OMCA5.js → chunk-TT6OU4UG.js} +2 -2
  24. package/js/{chunk-YEJOQEII.js → chunk-UOZMSUJ2.js} +61 -9
  25. package/js/chunk-UTJIGUSS.js +42 -0
  26. package/js/{chunk-G7ZIRKMK.js → chunk-VIU2XXA7.js} +228 -264
  27. package/js/{chunk-HDJH3RPR.js → chunk-VJQXXOQ3.js} +4 -4
  28. package/js/{chunk-WFSQXYUT.js → chunk-WPBR4AWB.js} +523 -63
  29. package/js/{chunk-SATWJKN6.js → chunk-YQ35E7KS.js} +2 -2
  30. package/js/chunk-ZUKBIHMK.js +92 -0
  31. package/js/client.js +122 -88
  32. package/js/contracts.js +116 -25
  33. package/js/effect.js +19 -20
  34. package/js/{es-APDZKREY.js → es-DIULA3ZF.js} +62 -1659
  35. package/js/graphql.js +57 -55
  36. package/js/host.js +19 -20
  37. package/js/index.js +245 -212
  38. package/js/mcp/effect.js +23 -22
  39. package/js/mcp/stdio.js +34 -30
  40. package/js/mcp.js +104 -68
  41. package/js/openapi.js +4087 -1503
  42. package/js/react.js +2 -3
  43. package/js/skills/effect.js +6 -3
  44. package/js/skills.js +147 -65
  45. package/js/storage/facet.js +1 -540
  46. package/js/ui/auth/contracts.js +2 -2
  47. package/js/ui/auth.js +5 -5
  48. package/js/ui/contracts.js +5 -4
  49. package/js/ui/serving.js +8517 -214
  50. package/package.json +2 -3
  51. package/runtime.json +1 -1
  52. package/types/app-data/src/contracts/database.d.ts +33 -6
  53. package/types/apps/src/contracts/api-response-error.d.ts +4 -0
  54. package/types/apps/src/contracts/app.d.ts +7 -8
  55. package/types/apps/src/contracts/cache.d.ts +14 -0
  56. package/types/apps/src/contracts/context.d.ts +12 -11
  57. package/types/apps/src/contracts/elicitation.d.ts +6 -6
  58. package/types/apps/src/contracts/failure.d.ts +54 -0
  59. package/types/apps/src/contracts/graphql.d.ts +2 -1
  60. package/types/apps/src/contracts/host.d.ts +44 -17
  61. package/types/apps/src/contracts/live.d.ts +2 -0
  62. package/types/apps/src/contracts/mcp.d.ts +96 -10
  63. package/types/apps/src/contracts/network.d.ts +84 -0
  64. package/types/apps/src/contracts/openapi-compile.d.ts +32 -3
  65. package/types/apps/src/contracts/openapi.d.ts +45 -9
  66. package/types/apps/src/contracts/operations.d.ts +8 -9
  67. package/types/apps/src/contracts/protocol-version.d.ts +2 -2
  68. package/types/apps/src/contracts/protocols/1.d.ts +263 -74
  69. package/types/apps/src/contracts/protocols/10.d.ts +1450 -0
  70. package/types/apps/src/contracts/protocols/2.d.ts +66 -24
  71. package/types/apps/src/contracts/protocols/3.d.ts +715 -0
  72. package/types/apps/src/contracts/protocols/4.d.ts +1297 -0
  73. package/types/apps/src/contracts/protocols/5.d.ts +1174 -0
  74. package/types/apps/src/contracts/protocols/6.d.ts +1620 -0
  75. package/types/apps/src/contracts/protocols/7.d.ts +1784 -0
  76. package/types/apps/src/contracts/protocols/8.d.ts +1130 -0
  77. package/types/apps/src/contracts/protocols/9.d.ts +1106 -0
  78. package/types/apps/src/contracts/protocols/oauth.d.ts +89 -0
  79. package/types/apps/src/contracts/provider-error.d.ts +9 -0
  80. package/types/apps/src/contracts/provider.d.ts +115 -10
  81. package/types/apps/src/contracts/router.d.ts +59 -0
  82. package/types/apps/src/contracts/skills.d.ts +39 -9
  83. package/types/apps/src/contracts/sql.d.ts +58 -0
  84. package/types/apps/src/contracts/ui.d.ts +19 -1
  85. package/types/apps/src/contracts/workflows.d.ts +40 -3
  86. package/types/apps/src/facet.d.ts +4 -5
  87. package/types/apps/src/graphql.d.ts +1 -3
  88. package/types/apps/src/implementation/account-router.d.ts +12 -0
  89. package/types/apps/src/implementation/app.d.ts +5 -4
  90. package/types/apps/src/implementation/browser-scripts.gen.d.ts +6 -0
  91. package/types/apps/src/implementation/catalog-cache.d.ts +32 -5
  92. package/types/apps/src/implementation/elicitation.d.ts +12 -12
  93. package/types/apps/src/implementation/failure-detail.d.ts +47 -0
  94. package/types/apps/src/implementation/graphql-catalog.d.ts +4 -7
  95. package/types/apps/src/implementation/graphql.d.ts +4 -3
  96. package/types/apps/src/implementation/input-problems.d.ts +6 -2
  97. package/types/apps/src/implementation/live.d.ts +2 -2
  98. package/types/apps/src/implementation/mcp-call.d.ts +6 -5
  99. package/types/apps/src/implementation/mcp-catalog.d.ts +7 -8
  100. package/types/apps/src/implementation/mcp-client.d.ts +49 -25
  101. package/types/apps/src/implementation/mcp-stdio.d.ts +1 -1
  102. package/types/apps/src/implementation/mcp-tools.d.ts +2 -1
  103. package/types/apps/src/implementation/mcp.d.ts +52 -25
  104. package/types/apps/src/implementation/network.d.ts +16 -0
  105. package/types/apps/src/implementation/openapi-compile.d.ts +27 -6
  106. package/types/apps/src/implementation/openapi-document.d.ts +46 -19
  107. package/types/apps/src/implementation/openapi-names.d.ts +9 -4
  108. package/types/apps/src/implementation/openapi-request.d.ts +10 -2
  109. package/types/apps/src/implementation/openapi-source.d.ts +8 -6
  110. package/types/apps/src/implementation/openapi-upgrade.d.ts +4 -0
  111. package/types/apps/src/implementation/operations.d.ts +36 -3
  112. package/types/apps/src/implementation/optimistic.d.ts +1 -1
  113. package/types/apps/src/implementation/protocol-operations.d.ts +6 -4
  114. package/types/apps/src/implementation/provider-error.d.ts +28 -1
  115. package/types/apps/src/implementation/provider.d.ts +19 -5
  116. package/types/apps/src/implementation/query-commit.d.ts +1 -1
  117. package/types/apps/src/implementation/router-catalog.d.ts +223 -0
  118. package/types/apps/src/implementation/router.d.ts +68 -0
  119. package/types/apps/src/implementation/runtime-yield.d.ts +7 -0
  120. package/types/apps/src/implementation/schema.d.ts +95 -11
  121. package/types/apps/src/implementation/skills.d.ts +18 -24
  122. package/types/apps/src/implementation/sql.d.ts +66 -0
  123. package/types/apps/src/implementation/ui-account-notice.d.ts +9 -0
  124. package/types/apps/src/implementation/ui-auth.d.ts +1 -1
  125. package/types/apps/src/implementation/ui-client.d.ts +2 -2
  126. package/types/apps/src/implementation/ui-document.d.ts +5 -0
  127. package/types/apps/src/implementation/ui-errors.d.ts +1 -1
  128. package/types/apps/src/implementation/ui-serving.d.ts +11 -5
  129. package/types/apps/src/implementation/ui-watch.d.ts +1 -1
  130. package/types/apps/src/implementation/upstream-error.d.ts +7 -0
  131. package/types/apps/src/implementation/webhooks.d.ts +1 -1
  132. package/types/apps/src/implementation/workflow-context.d.ts +11 -3
  133. package/types/apps/src/index.d.ts +30 -13
  134. package/types/apps/src/mcp-stdio.d.ts +2 -5
  135. package/types/apps/src/mcp.d.ts +25 -5
  136. package/types/apps/src/openapi.d.ts +6 -6
  137. package/types/apps/src/react.d.ts +1 -1
  138. package/types/apps/src/skills.d.ts +10 -8
  139. package/types/telemetry/src/app-records.d.ts +42 -0
  140. package/types/telemetry/src/browser-operations.d.ts +6 -3
  141. package/types/telemetry/src/browser.d.ts +2 -2
  142. package/types/telemetry/src/config.d.ts +2 -2
  143. package/types/telemetry/src/layer.d.ts +2 -2
  144. package/types/telemetry/src/recorded-failure.d.ts +20 -0
  145. package/types/telemetry/src/relay.d.ts +2 -2
  146. package/types/telemetry/src/transport.d.ts +8 -1
  147. package/types/utils/src/api-error.d.ts +53 -0
  148. package/types/utils/src/recorded-message.d.ts +15 -0
  149. package/js/chunk-BMOIAIVR.js +0 -138
  150. package/js/chunk-DHUDODG5.js +0 -213
  151. package/js/chunk-FZJOYIZO.js +0 -19
  152. package/js/chunk-LGIYBDWA.js +0 -85
  153. package/js/chunk-M6ZRRIBI.js +0 -877
  154. package/js/chunk-PLCMJREA.js +0 -590
  155. package/js/chunk-PYUYJRSK.js +0 -93
  156. package/js/chunk-SWPD52J7.js +0 -35
  157. package/js/chunk-W7D7WVSY.js +0 -18
  158. package/js/chunk-Z5NMEGJN.js +0 -29
  159. package/js/chunk-ZJWDMTE3.js +0 -63
  160. package/types/app-data/src/implementation/cursor.d.ts +0 -10
  161. package/types/app-data/src/implementation/index-key.d.ts +0 -7
  162. package/types/app-data/src/implementation/promise.d.ts +0 -68
  163. package/types/app-data/src/implementation/range.d.ts +0 -8
  164. package/types/app-data/src/implementation/schema.d.ts +0 -33
  165. package/types/app-data/src/implementation/sqlite.d.ts +0 -11
  166. package/types/app-data/src/index.d.ts +0 -4
  167. package/types/apps/src/contracts/dynamic-tools.d.ts +0 -13
  168. package/types/apps/src/contracts/storage.d.ts +0 -68
  169. package/types/apps/src/implementation/account-operations.d.ts +0 -151
  170. package/types/apps/src/implementation/dynamic-tools.d.ts +0 -8
  171. package/types/apps/src/implementation/storage.d.ts +0 -13
@@ -0,0 +1,118 @@
1
+ import {
2
+ ProviderError,
3
+ maxUpstreamMessageLength
4
+ } from "./chunk-P7MGDPFD.js";
5
+ import {
6
+ AccountId
7
+ } from "./chunk-YQ35E7KS.js";
8
+ import {
9
+ Option_exports,
10
+ Schema_exports
11
+ } from "./chunk-MXDKXAY4.js";
12
+
13
+ // src/implementation/upstream-error.ts
14
+ var ErrorToken = Schema_exports.String.check(Schema_exports.isPattern(/^[A-Za-z0-9._-]{1,128}$/u));
15
+ var JsonRpcError = Schema_exports.Struct({
16
+ error: Schema_exports.Struct({ code: Schema_exports.Int, message: Schema_exports.String })
17
+ });
18
+ var OAuthError = Schema_exports.Struct({
19
+ error: ErrorToken,
20
+ error_description: Schema_exports.optional(Schema_exports.String)
21
+ });
22
+ var bounded = (message) => message.length <= maxUpstreamMessageLength ? message : `${message.slice(0, maxUpstreamMessageLength - 1)}\u2026`;
23
+ var isShortenedUpstream = (message) => message.length === maxUpstreamMessageLength && message.endsWith("\u2026");
24
+ var stated = (code, message) => ({
25
+ code,
26
+ ...message === void 0 || message === "" ? {} : { message: bounded(message) }
27
+ });
28
+ var bodyUpstreamError = (json) => {
29
+ const rpc = Schema_exports.decodeUnknownOption(JsonRpcError)(json);
30
+ if (Option_exports.isSome(rpc)) return stated(rpc.value.error.code, rpc.value.error.message);
31
+ const oauth = Schema_exports.decodeUnknownOption(OAuthError)(json);
32
+ if (Option_exports.isSome(oauth)) return stated(oauth.value.error, oauth.value.error_description);
33
+ return void 0;
34
+ };
35
+ var authParam = /([A-Za-z][A-Za-z0-9_-]*)\s*=\s*(?:"((?:[^"\\]|\\.)*)"|([^\s,"]+))/g;
36
+ var challengeUpstreamError = (header) => {
37
+ const bearer = header === void 0 ? -1 : header.search(/\bBearer\b/i);
38
+ if (header === void 0 || bearer === -1) return void 0;
39
+ const params = /* @__PURE__ */ new Map();
40
+ for (const [, name, quoted, token] of header.slice(bearer + "Bearer".length).matchAll(authParam))
41
+ if (name !== void 0 && !params.has(name.toLowerCase()))
42
+ params.set(name.toLowerCase(), quoted?.replace(/\\(.)/g, "$1") ?? token ?? "");
43
+ const code = Schema_exports.decodeUnknownOption(ErrorToken)(params.get("error"));
44
+ return Option_exports.isNone(code) ? void 0 : stated(code.value, params.get("error_description"));
45
+ };
46
+
47
+ // src/implementation/provider-error.ts
48
+ var providerError = ({
49
+ reason,
50
+ status,
51
+ accountId,
52
+ phase,
53
+ upstream
54
+ }) => new ProviderError({
55
+ reason,
56
+ ...status === void 0 ? {} : { status },
57
+ ...accountId === void 0 ? {} : { accountId },
58
+ ...phase === void 0 ? {} : { phase },
59
+ ...upstream === void 0 ? {} : { upstream }
60
+ });
61
+ function parseProviderError(error) {
62
+ return Schema_exports.decodeUnknownOption(ProviderError)(error).pipe(Option_exports.map(providerError));
63
+ }
64
+ function providerErrorDetail(error, detail) {
65
+ return providerError({
66
+ ...error,
67
+ phase: error.phase ?? detail.phase,
68
+ upstream: error.upstream ?? detail.upstream
69
+ });
70
+ }
71
+ function httpProviderError(status, headers = {}) {
72
+ const upstream = challengeUpstreamError(headers["www-authenticate"]);
73
+ if (status >= 500 && status <= 599)
74
+ return providerError({ reason: "unavailable", status, upstream });
75
+ if (status === 401) return providerError({ reason: "unauthorized", status, upstream });
76
+ if (status === 429) return providerError({ reason: "rate_limited", status, upstream });
77
+ if (status !== 403) return void 0;
78
+ const retry = headers["retry-after"];
79
+ if (headers["x-ratelimit-remaining"] === "0" || retry !== void 0 && (/^\d+$/.test(retry) || Number.isFinite(Date.parse(retry))))
80
+ return providerError({ reason: "rate_limited", status, upstream });
81
+ if (typeof upstream?.code === "string" && upstream.code.toLowerCase() === "insufficient_scope")
82
+ return providerError({ reason: "forbidden", status, upstream });
83
+ return providerError({ reason: "rejected", status, upstream });
84
+ }
85
+ function accountProviderError(error, accountId) {
86
+ const parsed = parseProviderError(error);
87
+ const account = Schema_exports.decodeUnknownOption(AccountId)(accountId);
88
+ if (Option_exports.isNone(parsed) || Option_exports.isNone(account)) return error;
89
+ return providerError({ ...parsed.value, accountId: account.value });
90
+ }
91
+ function graphqlProviderError(errors, status) {
92
+ const codes = errors.flatMap((error) => {
93
+ const parsed = Schema_exports.decodeUnknownOption(
94
+ Schema_exports.Struct({
95
+ type: Schema_exports.optional(Schema_exports.String),
96
+ extensions: Schema_exports.optional(Schema_exports.Struct({ code: Schema_exports.optional(Schema_exports.String) }))
97
+ })
98
+ )(error);
99
+ return Option_exports.isSome(parsed) ? [parsed.value.type, parsed.value.extensions?.code] : [];
100
+ });
101
+ if (codes.includes("RATE_LIMITED") || codes.includes("TOO_MANY_REQUESTS"))
102
+ return new ProviderError({ reason: "rate_limited", status });
103
+ if (codes.includes("UNAUTHENTICATED"))
104
+ return new ProviderError({ reason: "unauthorized", status });
105
+ if (codes.includes("FORBIDDEN")) return new ProviderError({ reason: "forbidden", status });
106
+ return void 0;
107
+ }
108
+
109
+ export {
110
+ isShortenedUpstream,
111
+ bodyUpstreamError,
112
+ providerError,
113
+ parseProviderError,
114
+ providerErrorDetail,
115
+ httpProviderError,
116
+ accountProviderError,
117
+ graphqlProviderError
118
+ };
@@ -1,26 +1,32 @@
1
1
  import {
2
2
  prepareElicitation
3
- } from "./chunk-6VRYO2BG.js";
3
+ } from "./chunk-AHGGO2VY.js";
4
4
  import {
5
5
  fromPromise
6
- } from "./chunk-PYUYJRSK.js";
6
+ } from "./chunk-MJZYV7IO.js";
7
+ import {
8
+ bodyUpstreamError
9
+ } from "./chunk-EM4UL26F.js";
7
10
  import {
8
11
  ElicitationFailed,
9
12
  McpError,
13
+ McpServerHeader,
10
14
  McpToolMetadata,
11
15
  McpToolResult,
16
+ RouterIcon,
12
17
  ToolResultObservation,
13
18
  defaultElicitationLimits,
14
19
  defaultMcpClientLimits,
15
20
  mcpSdkTimerCeilingMs
16
- } from "./chunk-3M2MEDNL.js";
21
+ } from "./chunk-OTCLXFLL.js";
17
22
  import {
18
- compileJsonSchemaDecoder,
19
- jsonSchemaDecoder
20
- } from "./chunk-WFSQXYUT.js";
23
+ jsonSchemaDecoder,
24
+ nestJsonSchema,
25
+ preparedJsonSchemaDecoder
26
+ } from "./chunk-WPBR4AWB.js";
21
27
  import {
22
28
  JsonObject
23
- } from "./chunk-SATWJKN6.js";
29
+ } from "./chunk-YQ35E7KS.js";
24
30
  import {
25
31
  Clock_exports,
26
32
  Deferred_exports,
@@ -29,29 +35,79 @@ import {
29
35
  Option_exports,
30
36
  Queue_exports,
31
37
  Schema_exports
32
- } from "./chunk-FW5HBOIK.js";
38
+ } from "./chunk-MXDKXAY4.js";
33
39
 
34
40
  // src/implementation/mcp-tools.ts
41
+ var resultFields = {
42
+ content: { type: "array", items: { type: "object" } },
43
+ structuredContent: { type: "object" },
44
+ isError: { type: "boolean" },
45
+ _meta: { type: "object" }
46
+ };
47
+ var definitionReference = /^#\/(?:\$defs|definitions)\/[^/]+$/;
48
+ var locating = /* @__PURE__ */ new Set(["$id", "$anchor", "$dynamicAnchor", "$recursiveAnchor"]);
49
+ var onlyDefinitionReferences = (value) => Array.isArray(value) ? value.every(onlyDefinitionReferences) : value === null || typeof value !== "object" ? true : Object.entries(value).every(
50
+ ([key, item]) => locating.has(key) || key === "$dynamicRef" || key === "$recursiveRef" ? false : key === "$ref" ? typeof item === "string" && definitionReference.test(item) : onlyDefinitionReferences(item)
51
+ );
52
+ var placed = (structuredContent, pointer) => {
53
+ if (onlyDefinitionReferences(structuredContent)) {
54
+ const { $defs, definitions, $schema: _draft, ...schema } = structuredContent;
55
+ return {
56
+ schema,
57
+ root: {
58
+ ...$defs === void 0 ? {} : { $defs },
59
+ ...definitions === void 0 ? {} : { definitions }
60
+ }
61
+ };
62
+ }
63
+ try {
64
+ return { schema: nestJsonSchema(structuredContent, pointer), root: {} };
65
+ } catch {
66
+ return { schema: structuredContent, root: {} };
67
+ }
68
+ };
69
+ var resultSchema = (structuredContent) => {
70
+ if (structuredContent === void 0)
71
+ return { type: "object", properties: resultFields, required: ["content"] };
72
+ const { schema, root } = placed(structuredContent, "#/anyOf/0/properties/structuredContent");
73
+ return {
74
+ // The envelope's keywords mean the same in every draft, so the server's draft applies.
75
+ ...structuredContent.$schema === void 0 ? {} : { $schema: structuredContent.$schema },
76
+ ...root,
77
+ anyOf: [
78
+ {
79
+ type: "object",
80
+ properties: { ...resultFields, structuredContent: schema, isError: { const: false } },
81
+ required: ["content", "structuredContent"]
82
+ },
83
+ {
84
+ type: "object",
85
+ properties: { ...resultFields, isError: { const: true } },
86
+ required: ["content", "isError"]
87
+ }
88
+ ]
89
+ };
90
+ };
35
91
  var adaptMcpTool = (client, tool) => Effect_exports.gen(function* () {
36
92
  const decoder = yield* jsonSchemaDecoder(tool.inputSchema).pipe(
37
93
  Effect_exports.mapError(() => new McpError({ phase: "schema", reason: "invalid_response" }))
38
94
  );
39
- const output = tool.outputSchema === void 0 ? void 0 : yield* Effect_exports.cached(
40
- compileJsonSchemaDecoder(tool.outputSchema).pipe(
41
- Effect_exports.mapError(() => new McpError({ phase: "schema", reason: "invalid_response" }))
42
- )
43
- );
95
+ const output = preparedJsonSchemaDecoder(resultSchema(tool.outputSchema));
96
+ const { outputSchema: _upstream, ...metadata } = tool;
44
97
  const adapted = {
45
- ...tool,
98
+ ...metadata,
46
99
  description: tool.description ?? tool.title ?? tool.name,
47
100
  input: decoder,
101
+ output: output.decoder,
48
102
  ...tool.annotations?.readOnlyHint === void 0 ? {} : { readOnly: tool.annotations.readOnlyHint },
49
103
  run: (context, input) => Effect_exports.gen(function* () {
50
104
  const arguments_ = yield* Schema_exports.decodeUnknownEffect(decoder)(input).pipe(
51
105
  Effect_exports.flatMap(Schema_exports.decodeUnknownEffect(JsonObject)),
52
106
  Effect_exports.mapError(() => new McpError({ phase: "call", reason: "invalid_input" }))
53
107
  );
54
- const outputDecoder = output === void 0 ? void 0 : yield* output;
108
+ yield* output.compile.pipe(
109
+ Effect_exports.mapError(() => new McpError({ phase: "schema", reason: "invalid_response" }))
110
+ );
55
111
  const result = yield* client.call(tool.name, arguments_, context);
56
112
  if (result.isError === true) {
57
113
  (yield* ToolResultObservation).failed();
@@ -60,17 +116,13 @@ var adaptMcpTool = (client, tool) => Effect_exports.gen(function* () {
60
116
  "error.type": "McpToolError"
61
117
  });
62
118
  }
63
- if (outputDecoder !== void 0 && !result.isError)
64
- yield* Schema_exports.decodeUnknownEffect(outputDecoder)(result.structuredContent).pipe(
65
- Effect_exports.mapError(() => new McpError({ phase: "call", reason: "invalid_response" }))
66
- );
67
119
  return result;
68
120
  })
69
121
  };
70
122
  return adapted;
71
123
  });
72
124
  var adaptMcpTools = (client) => Effect_exports.gen(function* () {
73
- const metadata = yield* client.list;
125
+ const { tools: metadata } = yield* client.list;
74
126
  const entries = yield* Effect_exports.forEach(
75
127
  metadata,
76
128
  (tool) => adaptMcpTool(client, tool).pipe(Effect_exports.map((adapted) => [tool.name, adapted]))
@@ -79,7 +131,11 @@ var adaptMcpTools = (client) => Effect_exports.gen(function* () {
79
131
  });
80
132
 
81
133
  // src/implementation/mcp-client.ts
82
- import { ListToolsResultSchema } from "@modelcontextprotocol/sdk/types.js";
134
+ import {
135
+ ErrorCode as ErrorCode2,
136
+ ListToolsResultSchema,
137
+ McpError as ProtocolError2
138
+ } from "@modelcontextprotocol/sdk/types.js";
83
139
 
84
140
  // src/implementation/mcp-call.ts
85
141
  import {
@@ -208,6 +264,20 @@ var mcpCall = (client, name, input, context, timeoutMs, failure) => Effect_expor
208
264
  );
209
265
 
210
266
  // src/implementation/mcp-client.ts
267
+ var clientCodes = /* @__PURE__ */ new Set([
268
+ ErrorCode2.RequestTimeout,
269
+ ErrorCode2.ConnectionClosed
270
+ ]);
271
+ var answeredError = (error) => {
272
+ if (!(error instanceof ProtocolError2) || clientCodes.has(error.code)) return void 0;
273
+ const prefix = `MCP error ${error.code}: `;
274
+ return bodyUpstreamError({
275
+ error: {
276
+ code: error.code,
277
+ message: error.message.startsWith(prefix) ? error.message.slice(prefix.length) : error.message
278
+ }
279
+ });
280
+ };
211
281
  var mcpJsonSchemaValidator = {
212
282
  getValidator(document) {
213
283
  const decoder = Effect_exports.runSync(jsonSchemaDecoder(document));
@@ -233,7 +303,7 @@ function mcpClient(withClient, timeoutMs, failure) {
233
303
  do {
234
304
  const page = yield* Effect_exports.tryPromise({
235
305
  // This session only reads metadata. listTools() also eagerly compiles
236
- // every output validator; mcpOperations validates the selected tool on call.
306
+ // every output validator; mcpRouter validates the selected tool on call.
237
307
  try: (signal) => client.request(
238
308
  { method: "tools/list", params: cursor === void 0 ? {} : { cursor } },
239
309
  ListToolsResultSchema,
@@ -263,18 +333,52 @@ function mcpClient(withClient, timeoutMs, failure) {
263
333
  cursors.add(cursor);
264
334
  }
265
335
  } while (cursor !== void 0);
266
- return [...tools.values()];
336
+ const info = client.getServerVersion();
337
+ const instructions = client.getInstructions();
338
+ const icons = info?.icons?.flatMap(
339
+ (icon) => Option_exports.toArray(Schema_exports.decodeUnknownOption(RouterIcon)(icon))
340
+ );
341
+ const server = Schema_exports.decodeUnknownOption(McpServerHeader)({
342
+ ...info?.name === void 0 ? {} : { name: info.name },
343
+ ...info?.title === void 0 ? {} : { title: info.title },
344
+ ...info?.version === void 0 ? {} : { version: info.version },
345
+ ...info?.description === void 0 ? {} : { description: info.description },
346
+ ...info?.websiteUrl === void 0 ? {} : { websiteUrl: info.websiteUrl },
347
+ ...icons === void 0 ? {} : { icons },
348
+ ...instructions === void 0 ? {} : { instructions }
349
+ });
350
+ return {
351
+ tools: [...tools.values()],
352
+ server: Option_exports.getOrElse(server, () => ({}))
353
+ };
267
354
  })
268
355
  ).pipe(Effect_exports.withSpan("provider.mcp.discover"));
356
+ const check = withClient(
357
+ "discover",
358
+ (client) => Effect_exports.tryPromise({
359
+ try: (signal) => client.request({ method: "tools/list", params: {} }, ListToolsResultSchema, {
360
+ signal,
361
+ timeout: timeoutMs
362
+ }),
363
+ catch: (error) => failure("discover", error)
364
+ }).pipe(
365
+ Effect_exports.asVoid,
366
+ Effect_exports.withSpan("provider.mcp.request", {
367
+ kind: "client",
368
+ attributes: { "rpc.system.name": "jsonrpc", "rpc.method": "tools/list" }
369
+ })
370
+ )
371
+ ).pipe(Effect_exports.withSpan("provider.mcp.check"));
269
372
  const call = (name, input, context) => withClient("call", (client) => mcpCall(client, name, input, context, timeoutMs, failure)).pipe(
270
373
  Effect_exports.withSpan("provider.mcp.call", { attributes: { "mcp.tool.name": name } })
271
374
  );
272
- return { list, call };
375
+ return { list, check, call };
273
376
  }
274
377
 
275
378
  export {
276
379
  adaptMcpTool,
277
380
  adaptMcpTools,
381
+ answeredError,
278
382
  mcpJsonSchemaValidator,
279
383
  mcpClient
280
384
  };
@@ -1,24 +1,35 @@
1
1
  import {
2
2
  CacheError
3
- } from "./chunk-LGIYBDWA.js";
3
+ } from "./chunk-P7MGDPFD.js";
4
4
  import {
5
5
  wrap
6
- } from "./chunk-WFSQXYUT.js";
6
+ } from "./chunk-WPBR4AWB.js";
7
7
  import {
8
8
  JsonObject
9
- } from "./chunk-SATWJKN6.js";
9
+ } from "./chunk-YQ35E7KS.js";
10
10
  import {
11
11
  Duration_exports,
12
12
  Effect_exports,
13
13
  Schema_exports
14
- } from "./chunk-FW5HBOIK.js";
14
+ } from "./chunk-MXDKXAY4.js";
15
15
 
16
16
  // src/implementation/catalog-cache.ts
17
+ var catalogScope = (options, credential, invalid) => {
18
+ const { account, cache } = options;
19
+ if (account === void 0)
20
+ return credential === void 0 ? Effect_exports.succeed(cache) : Effect_exports.fail(invalid("missing-account"));
21
+ if (cache === void 0) return Effect_exports.succeed(void 0);
22
+ return Effect_exports.try({
23
+ try: () => cache.forAccount(account),
24
+ catch: () => invalid("unselected-account")
25
+ });
26
+ };
17
27
  var schema = (decoder) => wrap(decoder, false);
18
28
  var Manifest = Schema_exports.Struct({
19
29
  revision: Schema_exports.String,
20
30
  pages: Schema_exports.Int,
21
- summaries: Schema_exports.Int
31
+ summaries: Schema_exports.Int,
32
+ header: Schema_exports.optionalKey(JsonObject)
22
33
  });
23
34
  var invoke = (work) => Effect_exports.tryPromise({ try: work, catch: (error) => error });
24
35
  var catalogCache = (options) => Effect_exports.gen(function* () {
@@ -35,9 +46,12 @@ var catalogCache = (options) => Effect_exports.gen(function* () {
35
46
  const retention = Duration_exports.toMillis(Duration_exports.fromInputUnsafe(freshFor)) + Duration_exports.toMillis(Duration_exports.fromInputUnsafe(staleFor)) + 3e5;
36
47
  const local = yield* Effect_exports.cached(options.load());
37
48
  const refresh = (context) => Effect_exports.gen(function* () {
38
- const tools = yield* options.load(context);
49
+ const { tools, header } = yield* options.load(context);
39
50
  const digest = yield* invoke(
40
- () => crypto.subtle.digest("SHA-256", new TextEncoder().encode(JSON.stringify(tools)))
51
+ () => crypto.subtle.digest(
52
+ "SHA-256",
53
+ new TextEncoder().encode(JSON.stringify({ tools, header: header ?? null }))
54
+ )
41
55
  );
42
56
  const revision = Array.from(
43
57
  new Uint8Array(digest),
@@ -104,7 +118,12 @@ var catalogCache = (options) => Effect_exports.gen(function* () {
104
118
  yield* pageOut();
105
119
  yield* summaryOut();
106
120
  yield* flush();
107
- return { revision, pages: pages2, summaries };
121
+ return {
122
+ revision,
123
+ pages: pages2,
124
+ summaries,
125
+ ...header === void 0 ? {} : { header: yield* json(header) }
126
+ };
108
127
  });
109
128
  const getOptions = {
110
129
  key,
@@ -113,7 +132,12 @@ var catalogCache = (options) => Effect_exports.gen(function* () {
113
132
  staleFor,
114
133
  load: (context) => Effect_exports.runPromise(refresh(context), { signal: context.signal })
115
134
  };
116
- const current = () => cache === void 0 ? Effect_exports.fail(new CacheError({ reason: "unavailable" })) : invoke(() => cache.get(getOptions));
135
+ let reading;
136
+ const current = () => cache === void 0 ? Effect_exports.fail(new CacheError({ reason: "unavailable" })) : invoke(
137
+ () => reading ??= cache.get(getOptions).finally(() => {
138
+ reading = void 0;
139
+ })
140
+ );
117
141
  if (options.revalidate) {
118
142
  if (cache === void 0) yield* local;
119
143
  else yield* invoke(() => cache.revalidate(getOptions));
@@ -140,14 +164,17 @@ var catalogCache = (options) => Effect_exports.gen(function* () {
140
164
  return values;
141
165
  });
142
166
  const metadata = () => Effect_exports.gen(function* () {
143
- if (cache === void 0) return yield* local;
167
+ if (cache === void 0) return (yield* local).tools;
144
168
  const manifest = yield* current();
145
169
  return yield* pages(cache, manifest.revision, "page", manifest.pages, options.schema);
146
170
  });
147
171
  return {
148
172
  list: metadata,
173
+ /** The record stored with the current revision, if the source supplied one. */
174
+ header: () => cache === void 0 ? local.pipe(Effect_exports.map(({ header }) => header)) : current().pipe(Effect_exports.map((manifest) => manifest.header)),
149
175
  summaries: () => Effect_exports.gen(function* () {
150
- if (cache === void 0) return (yield* local).map((tool) => options.summary.of(tool));
176
+ if (cache === void 0)
177
+ return (yield* local).tools.map((tool) => options.summary.of(tool));
151
178
  const manifest = yield* current();
152
179
  return yield* pages(
153
180
  cache,
@@ -157,7 +184,7 @@ var catalogCache = (options) => Effect_exports.gen(function* () {
157
184
  options.summary.schema
158
185
  );
159
186
  }),
160
- resolve: (name) => cache === void 0 ? local.pipe(Effect_exports.map((tools) => tools.find((tool) => tool.name === name))) : current().pipe(
187
+ resolve: (name) => cache === void 0 ? local.pipe(Effect_exports.map(({ tools }) => tools.find((tool) => tool.name === name))) : current().pipe(
161
188
  Effect_exports.flatMap(
162
189
  (manifest) => invoke(
163
190
  () => cache.read(part(manifest.revision, "tool", name), schema(options.schema))
@@ -168,5 +195,6 @@ var catalogCache = (options) => Effect_exports.gen(function* () {
168
195
  });
169
196
 
170
197
  export {
198
+ catalogScope,
171
199
  catalogCache
172
200
  };
@@ -0,0 +1,156 @@
1
+ import {
2
+ declaredOperations,
3
+ fromPromise,
4
+ nativeOperation,
5
+ nativeRouter
6
+ } from "./chunk-MJZYV7IO.js";
7
+ import {
8
+ ScheduleTiming
9
+ } from "./chunk-OTCLXFLL.js";
10
+ import {
11
+ decoderOf,
12
+ isSchema,
13
+ schemaArgument
14
+ } from "./chunk-WPBR4AWB.js";
15
+ import {
16
+ JsonValue
17
+ } from "./chunk-YQ35E7KS.js";
18
+ import {
19
+ Effect_exports,
20
+ Schema_exports
21
+ } from "./chunk-MXDKXAY4.js";
22
+
23
+ // src/contracts/http.ts
24
+ var ResponseStatusError = class extends Schema_exports.TaggedError()(
25
+ "ResponseStatusError",
26
+ { status: Schema_exports.Number }
27
+ ) {
28
+ get message() {
29
+ return `Request failed with status ${this.status}`;
30
+ }
31
+ };
32
+ var ResponseDecodeError = class extends Schema_exports.TaggedError()(
33
+ "ResponseDecodeError",
34
+ {}
35
+ ) {
36
+ get message() {
37
+ return "Response body did not match the expected schema";
38
+ }
39
+ };
40
+
41
+ // src/implementation/workflows.ts
42
+ var NativeWorkflow = /* @__PURE__ */ Symbol("apps.Workflow");
43
+ var workflow = (options, run) => ({
44
+ [NativeWorkflow]: {
45
+ input: decoderOf(schemaArgument(options.input, "The workflow input")),
46
+ ...options.output === void 0 ? {} : { output: decoderOf(schemaArgument(options.output, "The workflow output")) },
47
+ ...options.description === void 0 ? {} : { description: options.description },
48
+ run: (context, input) => Effect_exports.tryPromise({
49
+ // SAFETY: defineApp checks required context; the host supplies the pinned run's capabilities.
50
+ try: () => run(context, input),
51
+ catch: (error) => error
52
+ })
53
+ }
54
+ });
55
+ var nativeWorkflow = (value) => {
56
+ if (typeof value !== "object" || value === null || !(NativeWorkflow in value)) return void 0;
57
+ return value[NativeWorkflow];
58
+ };
59
+
60
+ // src/implementation/app.ts
61
+ var InternalApp = /* @__PURE__ */ Symbol("apps.App");
62
+ var isApp = (value) => typeof value === "object" && value !== null && InternalApp in value;
63
+ var toEffectApp = (app) => app[InternalApp];
64
+ function rejectCatalogs(definition) {
65
+ if ("queries" in definition || "mutations" in definition)
66
+ throw new Error("Put queries and mutations in a router under tools");
67
+ }
68
+ function adaptDefinition(definition) {
69
+ rejectCatalogs(definition);
70
+ const webhooks = definition.webhooks === void 0 ? {} : {
71
+ webhooks: Object.fromEntries(
72
+ Object.entries(definition.webhooks).map(([name, webhook]) => [
73
+ name,
74
+ {
75
+ ...webhook,
76
+ ...webhook.register === void 0 ? {} : { register: fromPromise(webhook.register) },
77
+ handle: fromPromise(webhook.handle),
78
+ ...webhook.unregister === void 0 ? {} : { unregister: fromPromise(webhook.unregister) },
79
+ ..."config" in webhook && isSchema(webhook.config) ? { config: decoderOf(webhook.config) } : {},
80
+ ..."state" in webhook && isSchema(webhook.state) ? { state: decoderOf(webhook.state) } : {}
81
+ }
82
+ ])
83
+ )
84
+ };
85
+ const workflows = definition.workflows === void 0 ? {} : {
86
+ workflows: Object.fromEntries(
87
+ Object.entries(definition.workflows).map(([name, value]) => {
88
+ const declared2 = nativeWorkflow(value);
89
+ if (declared2 === void 0) throw new Error("Invalid workflow declaration");
90
+ return [name, declared2];
91
+ })
92
+ )
93
+ };
94
+ const root = definition.tools === void 0 ? void 0 : nativeRouter(definition.tools);
95
+ if (definition.tools !== void 0 && root === void 0)
96
+ throw new Error("tools must be a router");
97
+ const data = root === void 0 ? {} : { tools: root };
98
+ const declared = root?.kind === "router" ? declaredOperations(root) : [];
99
+ const mutations = /* @__PURE__ */ new Set();
100
+ for (const { operation } of declared) {
101
+ if (operation.kind !== "mutation") continue;
102
+ if (mutations.has(operation))
103
+ throw new Error("A mutation can be mounted at only one path in tools");
104
+ mutations.add(operation);
105
+ }
106
+ const schedules = definition.schedules === void 0 ? {} : {
107
+ schedules: Object.fromEntries(
108
+ Object.entries(definition.schedules).map(([name, schedule]) => {
109
+ const target = nativeOperation(schedule.operation);
110
+ const match = declared.find(
111
+ ({ operation }) => operation === target && operation.kind === "mutation"
112
+ );
113
+ if (match === void 0)
114
+ throw new Error("A schedule must reference a mutation in this app's tools");
115
+ return [
116
+ name,
117
+ {
118
+ timing: Schema_exports.decodeUnknownSync(ScheduleTiming)(schedule.timing),
119
+ input: Schema_exports.decodeUnknownSync(JsonValue)(schedule.input),
120
+ tool: match.name
121
+ }
122
+ ];
123
+ })
124
+ )
125
+ };
126
+ return {
127
+ ...definition,
128
+ ...webhooks,
129
+ ...workflows,
130
+ ...data,
131
+ ...schedules
132
+ };
133
+ }
134
+ var defineApp = (requirements, definition) => {
135
+ if (typeof definition !== "function") rejectCatalogs(definition);
136
+ const evaluate = typeof definition === "function" ? definition : async () => definition;
137
+ const factory = fromPromise(evaluate);
138
+ const native = {
139
+ accounts: requirements.accounts,
140
+ evaluate: (context) => factory(context).pipe(Effect_exports.map((value) => adaptDefinition(value)))
141
+ };
142
+ return {
143
+ [InternalApp]: native,
144
+ accounts: native.accounts,
145
+ evaluate: (context) => Effect_exports.runPromise(factory(context))
146
+ };
147
+ };
148
+
149
+ export {
150
+ ResponseStatusError,
151
+ ResponseDecodeError,
152
+ workflow,
153
+ isApp,
154
+ toEffectApp,
155
+ defineApp
156
+ };
@@ -0,0 +1,16 @@
1
+ import {
2
+ Predicate_exports
3
+ } from "./chunk-MXDKXAY4.js";
4
+
5
+ // ../utils/src/recorded-message.ts
6
+ var RecordedMessage = /* @__PURE__ */ Symbol.for("@executor-js/utils/RecordedMessage");
7
+ var recordedMessage = (error) => {
8
+ if (!Predicate_exports.hasProperty(error, RecordedMessage)) return void 0;
9
+ const message = error[RecordedMessage];
10
+ return typeof message === "string" ? message : void 0;
11
+ };
12
+
13
+ export {
14
+ RecordedMessage,
15
+ recordedMessage
16
+ };