apps 0.0.1-beta.3 → 0.0.1-beta.31

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 (140) hide show
  1. package/README.md +68 -44
  2. package/framework-reference.json +1 -1
  3. package/js/{chunk-RN2MXB4R.js → chunk-3FJYVAE4.js} +128 -24
  4. package/js/chunk-4OKYLVU4.js +118 -0
  5. package/js/{chunk-LGIYBDWA.js → chunk-5DLG2FVN.js} +65 -1
  6. package/js/{chunk-PLCMJREA.js → chunk-5JVNM3CQ.js} +60 -20
  7. package/js/chunk-5XJR4XGW.js +254 -0
  8. package/js/{chunk-FZJOYIZO.js → chunk-6KG4DZD7.js} +1 -1
  9. package/js/{chunk-EVJUVWN2.js → chunk-6ZJ2H6P4.js} +2 -2
  10. package/js/{chunk-NQ3OMCA5.js → chunk-AUFVX4KM.js} +2 -2
  11. package/js/{chunk-D47C7KG5.js → chunk-AYM2FUI5.js} +2 -2
  12. package/js/{chunk-5MQZEB6Y.js → chunk-BGALSHLT.js} +37 -12
  13. package/js/{chunk-QKHR7BMF.js → chunk-CJY5X26R.js} +3 -3
  14. package/js/{chunk-M6ZRRIBI.js → chunk-DASNNAP4.js} +1 -1
  15. package/js/{chunk-ZCAMUXSG.js → chunk-ETLILMHY.js} +3 -4
  16. package/js/{chunk-FW5HBOIK.js → chunk-EXGKN554.js} +2005 -1710
  17. package/js/{chunk-SATWJKN6.js → chunk-FBBXFFFJ.js} +1 -1
  18. package/js/{chunk-JN55AYQH.js → chunk-FULRJSWU.js} +61 -32
  19. package/js/{chunk-HDTGZWP2.js → chunk-GG566OOE.js} +139 -32
  20. package/js/chunk-GZ4UHXRT.js +92 -0
  21. package/js/{chunk-YEJOQEII.js → chunk-HW3DPBZR.js} +45 -7
  22. package/js/{chunk-HDJH3RPR.js → chunk-MFHUR5SB.js} +2 -2
  23. package/js/{chunk-MYYEW3RA.js → chunk-N72RKJ5E.js} +984 -61
  24. package/js/{chunk-WFSQXYUT.js → chunk-NPGRURDG.js} +390 -18
  25. package/js/chunk-OD3KFKZD.js +1617 -0
  26. package/js/{chunk-FDNTX5QJ.js → chunk-OX233L7N.js} +2 -2
  27. package/js/{chunk-G7ZIRKMK.js → chunk-QYM4STZW.js} +118 -197
  28. package/js/chunk-RULZPNGP.js +801 -0
  29. package/js/{chunk-BMOIAIVR.js → chunk-UMCMZFXW.js} +49 -1
  30. package/js/{chunk-J7O55ZV7.js → chunk-W7F23NQ2.js} +419 -191
  31. package/js/chunk-WG5DFZFT.js +42 -0
  32. package/js/{chunk-T2LAZCAD.js → chunk-ZOY7PDMI.js} +1 -1
  33. package/js/client.js +120 -84
  34. package/js/contracts.js +110 -16
  35. package/js/effect.js +20 -20
  36. package/js/{es-APDZKREY.js → es-DIULA3ZF.js} +62 -1659
  37. package/js/graphql.js +58 -54
  38. package/js/host.js +20 -20
  39. package/js/index.js +247 -204
  40. package/js/mcp/effect.js +24 -22
  41. package/js/mcp/stdio.js +35 -30
  42. package/js/mcp.js +105 -68
  43. package/js/openapi.js +4087 -1503
  44. package/js/react.js +3 -3
  45. package/js/skills/effect.js +5 -3
  46. package/js/skills.js +15 -15
  47. package/js/storage/facet.js +4 -4
  48. package/js/ui/auth/contracts.js +2 -2
  49. package/js/ui/auth.js +5 -5
  50. package/js/ui/contracts.js +5 -4
  51. package/js/ui/serving.js +8516 -214
  52. package/package.json +1 -1
  53. package/runtime.json +1 -1
  54. package/types/app-data/src/contracts/database.d.ts +33 -6
  55. package/types/app-data/src/implementation/schema.d.ts +2 -17
  56. package/types/apps/src/contracts/api-response-error.d.ts +4 -0
  57. package/types/apps/src/contracts/app.d.ts +7 -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 +34 -11
  61. package/types/apps/src/contracts/mcp.d.ts +91 -10
  62. package/types/apps/src/contracts/network.d.ts +84 -0
  63. package/types/apps/src/contracts/openapi-compile.d.ts +31 -3
  64. package/types/apps/src/contracts/openapi.d.ts +45 -9
  65. package/types/apps/src/contracts/operations.d.ts +5 -6
  66. package/types/apps/src/contracts/protocol-version.d.ts +2 -2
  67. package/types/apps/src/contracts/protocols/1.d.ts +251 -69
  68. package/types/apps/src/contracts/protocols/2.d.ts +710 -0
  69. package/types/apps/src/contracts/protocols/3.d.ts +716 -0
  70. package/types/apps/src/contracts/protocols/4.d.ts +1298 -0
  71. package/types/apps/src/contracts/protocols/5.d.ts +1174 -0
  72. package/types/apps/src/contracts/protocols/6.d.ts +1620 -0
  73. package/types/apps/src/contracts/protocols/7.d.ts +1784 -0
  74. package/types/apps/src/contracts/protocols/8.d.ts +1119 -0
  75. package/types/apps/src/contracts/protocols/oauth.d.ts +89 -0
  76. package/types/apps/src/contracts/provider-error.d.ts +9 -0
  77. package/types/apps/src/contracts/provider.d.ts +115 -10
  78. package/types/apps/src/contracts/router.d.ts +59 -0
  79. package/types/apps/src/contracts/skills.d.ts +18 -5
  80. package/types/apps/src/contracts/storage.d.ts +3 -3
  81. package/types/apps/src/contracts/ui.d.ts +18 -0
  82. package/types/apps/src/contracts/workflows.d.ts +34 -3
  83. package/types/apps/src/graphql.d.ts +1 -3
  84. package/types/apps/src/implementation/account-router.d.ts +12 -0
  85. package/types/apps/src/implementation/app.d.ts +5 -4
  86. package/types/apps/src/implementation/browser-scripts.gen.d.ts +6 -0
  87. package/types/apps/src/implementation/catalog-cache.d.ts +34 -4
  88. package/types/apps/src/implementation/elicitation.d.ts +9 -9
  89. package/types/apps/src/implementation/failure-detail.d.ts +46 -0
  90. package/types/apps/src/implementation/graphql-catalog.d.ts +4 -7
  91. package/types/apps/src/implementation/graphql.d.ts +4 -3
  92. package/types/apps/src/implementation/input-problems.d.ts +4 -1
  93. package/types/apps/src/implementation/mcp-call.d.ts +6 -5
  94. package/types/apps/src/implementation/mcp-catalog.d.ts +7 -8
  95. package/types/apps/src/implementation/mcp-client.d.ts +49 -25
  96. package/types/apps/src/implementation/mcp-stdio.d.ts +1 -1
  97. package/types/apps/src/implementation/mcp-tools.d.ts +2 -1
  98. package/types/apps/src/implementation/mcp.d.ts +52 -25
  99. package/types/apps/src/implementation/network.d.ts +16 -0
  100. package/types/apps/src/implementation/openapi-compile.d.ts +27 -6
  101. package/types/apps/src/implementation/openapi-document.d.ts +46 -19
  102. package/types/apps/src/implementation/openapi-names.d.ts +9 -4
  103. package/types/apps/src/implementation/openapi-request.d.ts +10 -2
  104. package/types/apps/src/implementation/openapi-source.d.ts +8 -6
  105. package/types/apps/src/implementation/openapi-upgrade.d.ts +4 -0
  106. package/types/apps/src/implementation/operations.d.ts +36 -3
  107. package/types/apps/src/implementation/protocol-operations.d.ts +6 -4
  108. package/types/apps/src/implementation/provider-error.d.ts +28 -1
  109. package/types/apps/src/implementation/provider.d.ts +19 -5
  110. package/types/apps/src/implementation/router-catalog.d.ts +224 -0
  111. package/types/apps/src/implementation/router.d.ts +68 -0
  112. package/types/apps/src/implementation/runtime-yield.d.ts +7 -0
  113. package/types/apps/src/implementation/schema.d.ts +80 -1
  114. package/types/apps/src/implementation/skills.d.ts +2 -2
  115. package/types/apps/src/implementation/storage.d.ts +5 -3
  116. package/types/apps/src/implementation/ui-account-notice.d.ts +9 -0
  117. package/types/apps/src/implementation/ui-client.d.ts +2 -2
  118. package/types/apps/src/implementation/ui-document.d.ts +5 -0
  119. package/types/apps/src/implementation/ui-errors.d.ts +1 -1
  120. package/types/apps/src/implementation/ui-serving.d.ts +10 -4
  121. package/types/apps/src/implementation/ui-watch.d.ts +1 -1
  122. package/types/apps/src/implementation/upstream-error.d.ts +7 -0
  123. package/types/apps/src/implementation/webhooks.d.ts +1 -1
  124. package/types/apps/src/implementation/workflow-context.d.ts +11 -3
  125. package/types/apps/src/index.d.ts +29 -11
  126. package/types/apps/src/mcp-stdio.d.ts +2 -5
  127. package/types/apps/src/mcp.d.ts +25 -5
  128. package/types/apps/src/openapi.d.ts +6 -6
  129. package/types/apps/src/skills.d.ts +4 -4
  130. package/types/telemetry/src/browser-operations.d.ts +5 -2
  131. package/types/telemetry/src/config.d.ts +2 -2
  132. package/types/utils/src/api-error.d.ts +48 -0
  133. package/js/chunk-PYUYJRSK.js +0 -93
  134. package/js/chunk-SWPD52J7.js +0 -35
  135. package/js/chunk-W7D7WVSY.js +0 -18
  136. package/js/chunk-Z5NMEGJN.js +0 -29
  137. package/js/chunk-ZJWDMTE3.js +0 -63
  138. package/types/apps/src/contracts/dynamic-tools.d.ts +0 -13
  139. package/types/apps/src/implementation/account-operations.d.ts +0 -151
  140. package/types/apps/src/implementation/dynamic-tools.d.ts +0 -8
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  Schema_exports
3
- } from "./chunk-FW5HBOIK.js";
3
+ } from "./chunk-EXGKN554.js";
4
4
 
5
5
  // src/contracts/schema.ts
6
6
  var JsonValue = Schema_exports.Json;
@@ -1,29 +1,51 @@
1
1
  import {
2
- parseDatabaseSchema,
3
2
  promiseTable
4
- } from "./chunk-PLCMJREA.js";
3
+ } from "./chunk-5JVNM3CQ.js";
5
4
  import {
5
+ declaredOperations,
6
6
  fromPromise,
7
- nativeOperation
8
- } from "./chunk-PYUYJRSK.js";
7
+ nativeOperation,
8
+ nativeRouter
9
+ } from "./chunk-5XJR4XGW.js";
9
10
  import {
10
11
  ScheduleTiming
11
- } from "./chunk-MYYEW3RA.js";
12
+ } from "./chunk-N72RKJ5E.js";
13
+ import {
14
+ DatabaseSchema
15
+ } from "./chunk-UMCMZFXW.js";
12
16
  import {
13
17
  decoderOf,
14
18
  isSchema,
15
19
  storageFieldOf
16
- } from "./chunk-WFSQXYUT.js";
20
+ } from "./chunk-NPGRURDG.js";
17
21
  import {
18
22
  AppStorageUnavailable
19
- } from "./chunk-FZJOYIZO.js";
23
+ } from "./chunk-6KG4DZD7.js";
20
24
  import {
21
25
  JsonValue
22
- } from "./chunk-SATWJKN6.js";
26
+ } from "./chunk-FBBXFFFJ.js";
23
27
  import {
24
28
  Effect_exports,
25
29
  Schema_exports
26
- } from "./chunk-FW5HBOIK.js";
30
+ } from "./chunk-EXGKN554.js";
31
+
32
+ // src/contracts/http.ts
33
+ var ResponseStatusError = class extends Schema_exports.TaggedError()(
34
+ "ResponseStatusError",
35
+ { status: Schema_exports.Number }
36
+ ) {
37
+ get message() {
38
+ return `Request failed with status ${this.status}`;
39
+ }
40
+ };
41
+ var ResponseDecodeError = class extends Schema_exports.TaggedError()(
42
+ "ResponseDecodeError",
43
+ {}
44
+ ) {
45
+ get message() {
46
+ return "Response body did not match the expected schema";
47
+ }
48
+ };
27
49
 
28
50
  // src/implementation/workflows.ts
29
51
  var NativeWorkflow = /* @__PURE__ */ Symbol("apps.Workflow");
@@ -48,8 +70,12 @@ var nativeWorkflow = (value) => {
48
70
  var InternalApp = /* @__PURE__ */ Symbol("apps.App");
49
71
  var isApp = (value) => typeof value === "object" && value !== null && InternalApp in value;
50
72
  var toEffectApp = (app) => app[InternalApp];
73
+ function rejectCatalogs(definition) {
74
+ if ("queries" in definition || "mutations" in definition)
75
+ throw new Error("Put queries and mutations in a router under tools");
76
+ }
51
77
  function adaptDefinition(definition) {
52
- if ("tools" in definition) throw new Error("Use queries and mutations instead of tools");
78
+ rejectCatalogs(definition);
53
79
  const webhooks = definition.webhooks === void 0 ? {} : {
54
80
  webhooks: Object.fromEntries(
55
81
  Object.entries(definition.webhooks).map(([name, webhook]) => [
@@ -65,42 +91,42 @@ function adaptDefinition(definition) {
65
91
  ])
66
92
  )
67
93
  };
68
- const operations = (kind, catalog) => Object.fromEntries(
69
- Object.entries(catalog).map(([name, value]) => {
70
- const operation = nativeOperation(value);
71
- if (operation === void 0 || operation.kind !== kind)
72
- throw new Error("Invalid app data operation");
73
- return [name, operation];
74
- })
75
- );
76
94
  const workflows = definition.workflows === void 0 ? {} : {
77
95
  workflows: Object.fromEntries(
78
96
  Object.entries(definition.workflows).map(([name, value]) => {
79
- const declared = nativeWorkflow(value);
80
- if (declared === void 0) throw new Error("Invalid workflow declaration");
81
- return [name, declared];
97
+ const declared2 = nativeWorkflow(value);
98
+ if (declared2 === void 0) throw new Error("Invalid workflow declaration");
99
+ return [name, declared2];
82
100
  })
83
101
  )
84
102
  };
85
- const data = {
86
- ...definition.queries === void 0 ? {} : { queries: operations("query", definition.queries) },
87
- ...definition.mutations === void 0 ? {} : { mutations: operations("mutation", definition.mutations) }
88
- };
103
+ const root = definition.tools === void 0 ? void 0 : nativeRouter(definition.tools);
104
+ if (definition.tools !== void 0 && root === void 0)
105
+ throw new Error("tools must be a router");
106
+ const data = root === void 0 ? {} : { tools: root };
107
+ const declared = root?.kind === "router" ? declaredOperations(root) : [];
108
+ const mutations = /* @__PURE__ */ new Set();
109
+ for (const { operation } of declared) {
110
+ if (operation.kind !== "mutation") continue;
111
+ if (mutations.has(operation))
112
+ throw new Error("A mutation can be mounted at only one path in tools");
113
+ mutations.add(operation);
114
+ }
89
115
  const schedules = definition.schedules === void 0 ? {} : {
90
116
  schedules: Object.fromEntries(
91
117
  Object.entries(definition.schedules).map(([name, schedule]) => {
92
- const matches = Object.entries(definition.mutations ?? {}).filter(
93
- ([, operation]) => operation === schedule.operation
118
+ const target = nativeOperation(schedule.operation);
119
+ const match = declared.find(
120
+ ({ operation }) => operation === target && operation.kind === "mutation"
94
121
  );
95
- const match = matches[0];
96
- if (match === void 0 || matches.length !== 1)
97
- throw new Error("A schedule must reference exactly one named mutation in this app");
122
+ if (match === void 0)
123
+ throw new Error("A schedule must reference a mutation in this app's tools");
98
124
  return [
99
125
  name,
100
126
  {
101
127
  timing: Schema_exports.decodeUnknownSync(ScheduleTiming)(schedule.timing),
102
128
  input: Schema_exports.decodeUnknownSync(JsonValue)(schedule.input),
103
- tool: `mutations.${match[0]}`
129
+ tool: match.name
104
130
  }
105
131
  ];
106
132
  })
@@ -115,6 +141,7 @@ function adaptDefinition(definition) {
115
141
  };
116
142
  }
117
143
  var defineApp = (requirements, definition) => {
144
+ if (typeof definition !== "function") rejectCatalogs(definition);
118
145
  const evaluate = typeof definition === "function" ? definition : async () => definition;
119
146
  const factory = fromPromise(evaluate);
120
147
  const native = {
@@ -152,7 +179,7 @@ var serialize = (tables) => {
152
179
  }
153
180
  ])
154
181
  );
155
- return Effect_exports.runSync(parseDatabaseSchema(definitions));
182
+ return Schema_exports.decodeUnknownSync(DatabaseSchema)(definitions);
156
183
  };
157
184
  var authorDatabase = (tables, session, signal, writable) => {
158
185
  return Object.fromEntries(
@@ -202,6 +229,8 @@ var unavailableStorage = {
202
229
  };
203
230
 
204
231
  export {
232
+ ResponseStatusError,
233
+ ResponseDecodeError,
205
234
  workflow,
206
235
  isApp,
207
236
  toEffectApp,
@@ -1,37 +1,52 @@
1
1
  import {
2
2
  adaptMcpTools,
3
+ answeredError,
3
4
  mcpClient,
4
5
  mcpJsonSchemaValidator
5
- } from "./chunk-RN2MXB4R.js";
6
+ } from "./chunk-3FJYVAE4.js";
7
+ import {
8
+ failOnNetworkRefusal
9
+ } from "./chunk-RULZPNGP.js";
6
10
  import {
7
11
  accountProviderError,
8
- httpProviderError
9
- } from "./chunk-ZJWDMTE3.js";
12
+ bodyUpstreamError,
13
+ httpProviderError,
14
+ providerErrorDetail
15
+ } from "./chunk-4OKYLVU4.js";
10
16
  import {
17
+ McpCredentialsUnverified,
11
18
  McpError,
19
+ McpHealthInput,
12
20
  McpToolsOptions,
13
- defaultMcpClientLimits
14
- } from "./chunk-MYYEW3RA.js";
21
+ NetworkRefused,
22
+ defaultMcpClientLimits,
23
+ mcpHealthReserveMs
24
+ } from "./chunk-N72RKJ5E.js";
15
25
  import {
16
26
  ProviderError
17
- } from "./chunk-W7D7WVSY.js";
27
+ } from "./chunk-5DLG2FVN.js";
18
28
  import {
19
29
  captureTelemetry
20
- } from "./chunk-ZCAMUXSG.js";
30
+ } from "./chunk-ETLILMHY.js";
21
31
  import {
22
32
  FetchHttpClient_exports
23
- } from "./chunk-HDJH3RPR.js";
33
+ } from "./chunk-MFHUR5SB.js";
24
34
  import {
25
35
  HttpClientRequest_exports,
26
36
  HttpClient_exports
27
- } from "./chunk-QKHR7BMF.js";
37
+ } from "./chunk-CJY5X26R.js";
28
38
  import {
39
+ Clock_exports,
29
40
  Deferred_exports,
30
41
  Effect_exports,
42
+ Match_exports,
43
+ Option_exports,
44
+ Predicate_exports,
31
45
  Redacted_exports,
46
+ Ref_exports,
32
47
  Schema_exports,
33
48
  Stream_exports
34
- } from "./chunk-FW5HBOIK.js";
49
+ } from "./chunk-EXGKN554.js";
35
50
 
36
51
  // src/implementation/mcp.ts
37
52
  import { UnauthorizedError } from "@modelcontextprotocol/sdk/client/auth.js";
@@ -46,18 +61,45 @@ import {
46
61
  StreamableHTTPClientTransport,
47
62
  StreamableHTTPError
48
63
  } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
64
+ var unreadable = (error) => error instanceof SyntaxError || error instanceof Error && Predicate_exports.hasProperty(error, "issues") && Array.isArray(error.issues);
49
65
  var failure = (phase, error) => {
50
- if (Schema_exports.is(ProviderError)(error) || Schema_exports.is(McpError)(error)) return error;
51
- const status = error instanceof UnauthorizedError ? 401 : error instanceof StreamableHTTPError || error instanceof SseError ? error.code : void 0;
52
- const provider = status === void 0 ? void 0 : httpProviderError(status);
53
- if (provider !== void 0) return provider;
66
+ if (Schema_exports.is(ProviderError)(error) || Schema_exports.is(McpError)(error) || Schema_exports.is(NetworkRefused)(error))
67
+ return error;
68
+ const code = error instanceof UnauthorizedError ? 401 : error instanceof StreamableHTTPError || error instanceof SseError ? error.code : void 0;
69
+ if (code !== void 0 && code >= 300 && code <= 599)
70
+ return httpProviderError(code) ?? new McpError({ phase, reason: "request", status: code });
71
+ const upstream = answeredError(error);
54
72
  return new McpError({
55
73
  phase,
56
- reason: error instanceof ProtocolError && error.code === ErrorCode.RequestTimeout ? "timeout" : "request",
57
- ...status === void 0 ? {} : { status }
74
+ reason: code !== void 0 || unreadable(error) ? "invalid_response" : error instanceof ProtocolError && error.code === ErrorCode.RequestTimeout ? "timeout" : "request",
75
+ ...upstream === void 0 ? {} : { upstream }
58
76
  });
59
77
  };
60
- var transportFetch = (connection, telemetry, rejected) => (url, init) => Effect_exports.runPromiseWith(telemetry.context)(
78
+ var errorBodyLimits = { maxBytes: 65536, readTimeoutMs: 2e3 };
79
+ var errorBody = (response) => Effect_exports.gen(function* () {
80
+ const json = /^application\/(?:[\w.-]+\+)?json$/i.test(
81
+ response.headers["content-type"]?.split(";")[0]?.trim() ?? ""
82
+ );
83
+ const length = response.headers["content-length"];
84
+ if (!json || length !== void 0 && Number(length) > errorBodyLimits.maxBytes)
85
+ return { body: Stream_exports.toReadableStream(response.stream), upstream: void 0 };
86
+ const unreadable2 = new McpError({ phase: "transport", reason: "invalid_response" });
87
+ const read = yield* response.stream.pipe(
88
+ Stream_exports.mapError(() => unreadable2),
89
+ Stream_exports.limitBytes(errorBodyLimits.maxBytes, () => Stream_exports.fail(unreadable2)),
90
+ Stream_exports.decodeText,
91
+ Stream_exports.mkString,
92
+ Effect_exports.timeout(errorBodyLimits.readTimeoutMs),
93
+ Effect_exports.option
94
+ );
95
+ if (Option_exports.isNone(read)) return { body: null, upstream: void 0 };
96
+ const parsed = Schema_exports.decodeUnknownOption(Schema_exports.fromJsonString(Schema_exports.Json))(read.value);
97
+ return {
98
+ body: read.value,
99
+ upstream: Option_exports.isSome(parsed) ? bodyUpstreamError(parsed.value) : void 0
100
+ };
101
+ });
102
+ var transportFetch = (connection, telemetry, rejected, answered) => (url, init) => Effect_exports.runPromiseWith(telemetry.context)(
61
103
  Effect_exports.gen(function* () {
62
104
  const target = yield* Effect_exports.try({
63
105
  try: () => new URL(url),
@@ -67,26 +109,37 @@ var transportFetch = (connection, telemetry, rejected) => (url, init) => Effect_
67
109
  return yield* new McpError({ phase: "transport", reason: "invalid_input" });
68
110
  if (target.origin !== connection.url.origin || target.username || target.password)
69
111
  return yield* new McpError({ phase: "transport", reason: "invalid_response" });
70
- const headers = new Headers(Redacted_exports.value(connection.headers));
71
- new Headers(init?.headers).forEach((value, name) => headers.set(name, value));
72
112
  const request = yield* Effect_exports.try({
73
- try: () => HttpClientRequest_exports.fromWeb(new Request(target, { ...init, headers })),
74
- catch: () => failure("transport", void 0)
113
+ try: () => {
114
+ const headers = new Headers(Redacted_exports.value(connection.headers));
115
+ new Headers(init?.headers).forEach((value, name) => headers.set(name, value));
116
+ return HttpClientRequest_exports.fromWeb(new Request(target, { ...init, headers }));
117
+ },
118
+ // The provider's headers cannot form an HTTP request, such as a name with a space.
119
+ catch: () => new McpError({ phase: "transport", reason: "invalid_input" })
75
120
  });
76
121
  const client = yield* HttpClient_exports.HttpClient;
77
122
  const response = yield* client.execute(request);
123
+ yield* failOnNetworkRefusal(response).pipe(
124
+ Effect_exports.tapError((refused) => Deferred_exports.fail(rejected, refused))
125
+ );
126
+ if (response.status < 400)
127
+ return new Response(
128
+ [204, 205, 304].includes(response.status) ? null : Stream_exports.toReadableStream(response.stream),
129
+ {
130
+ status: response.status,
131
+ headers: response.headers
132
+ }
133
+ );
134
+ const { body, upstream } = yield* errorBody(response);
78
135
  const provider = httpProviderError(response.status, response.headers);
79
136
  if (provider !== void 0) {
80
- yield* Deferred_exports.fail(rejected, provider);
81
- return yield* provider;
137
+ const refused = providerErrorDetail(provider, { upstream });
138
+ yield* Deferred_exports.fail(rejected, refused);
139
+ return yield* refused;
82
140
  }
83
- return new Response(
84
- [204, 205, 304].includes(response.status) ? null : Stream_exports.toReadableStream(response.stream),
85
- {
86
- status: response.status,
87
- headers: response.headers
88
- }
89
- );
141
+ yield* Ref_exports.set(answered, { status: response.status, upstream });
142
+ return new Response(body, { status: response.status, headers: response.headers });
90
143
  }).pipe(
91
144
  Effect_exports.provide(FetchHttpClient_exports.layer),
92
145
  Effect_exports.provideService(FetchHttpClient_exports.RequestInit, { redirect: "manual" }),
@@ -104,15 +157,30 @@ var transportFetch = (connection, telemetry, rejected) => (url, init) => Effect_
104
157
  ),
105
158
  init?.signal ? { signal: init.signal } : {}
106
159
  );
160
+ var explain = (error, phase, response) => {
161
+ if (Schema_exports.is(ProviderError)(error)) return providerErrorDetail(error, { phase });
162
+ if (!Schema_exports.is(McpError)(error) || error.upstream !== void 0 || error.status === void 0 || response?.status !== error.status || response.upstream === void 0)
163
+ return error;
164
+ return new McpError({
165
+ phase: error.phase,
166
+ reason: error.reason,
167
+ status: error.status,
168
+ upstream: response.upstream
169
+ });
170
+ };
171
+ var explained = (phase, answered) => (error) => Ref_exports.get(answered).pipe(
172
+ Effect_exports.flatMap((response) => Effect_exports.fail(explain(error, phase, response)))
173
+ );
107
174
  function withClient(connection, mode, use, changed) {
108
175
  const attempt = (kind) => Effect_exports.scoped(
109
176
  Effect_exports.gen(function* () {
110
177
  const telemetry = yield* captureTelemetry;
111
178
  const rejected = yield* Deferred_exports.make();
179
+ const answered = yield* Ref_exports.make(void 0);
112
180
  const pending = /* @__PURE__ */ new Set();
113
181
  const { client, transport } = yield* Effect_exports.acquireRelease(
114
182
  Effect_exports.sync(() => {
115
- const fetch = transportFetch(connection, telemetry, rejected);
183
+ const fetch = transportFetch(connection, telemetry, rejected, answered);
116
184
  const client2 = new Client(
117
185
  { name: "executor-apps", version: "0.1.0" },
118
186
  {
@@ -168,10 +236,14 @@ function withClient(connection, mode, use, changed) {
168
236
  catch: (error) => failure("connect", error)
169
237
  }).pipe(
170
238
  Effect_exports.raceFirst(Deferred_exports.await(rejected)),
239
+ Effect_exports.catch(explained("connect", answered)),
171
240
  Effect_exports.timeout(connection.timeoutMs),
172
241
  Effect_exports.withSpan("provider.mcp.connect")
173
242
  );
174
- return yield* use(client).pipe(Effect_exports.raceFirst(Deferred_exports.await(rejected)));
243
+ return yield* use(client).pipe(
244
+ Effect_exports.raceFirst(Deferred_exports.await(rejected)),
245
+ Effect_exports.catch(explained(mode, answered))
246
+ );
175
247
  })
176
248
  ).pipe(
177
249
  Effect_exports.withSpan("provider.mcp.session", {
@@ -216,9 +288,44 @@ var mcpClientEffect = (input, changed) => Effect_exports.gen(function* () {
216
288
  failure
217
289
  );
218
290
  });
291
+ var refusesCredentials = (error) => Schema_exports.is(ProviderError)(error) && Match_exports.value(error.reason).pipe(
292
+ Match_exports.whenOr("unauthorized", "forbidden", "rejected", () => true),
293
+ Match_exports.whenOr("rate_limited", "unavailable", () => false),
294
+ Match_exports.exhaustive
295
+ );
296
+ var mcpHealthEffect = (check, options) => Effect_exports.gen(function* () {
297
+ const { deadline, timeoutMs, ...parsed } = yield* Schema_exports.decodeUnknownEffect(McpHealthInput)({
298
+ ...options,
299
+ accountId: check.account.id,
300
+ signal: check.signal,
301
+ deadline: check.deadline
302
+ }).pipe(Effect_exports.mapError(() => new McpError({ phase: "connect", reason: "invalid_input" })));
303
+ const end = Math.min(
304
+ (yield* Clock_exports.currentTimeMillis) + (timeoutMs ?? defaultMcpClientLimits.timeoutMs),
305
+ deadline === void 0 ? Number.POSITIVE_INFINITY : deadline - mcpHealthReserveMs
306
+ );
307
+ const remaining = Effect_exports.flatMap(
308
+ Clock_exports.currentTimeMillis,
309
+ (now) => end - now >= 1 ? Effect_exports.succeed(Math.floor(end - now)) : Effect_exports.fail(new McpError({ phase: "transport", reason: "timeout" }))
310
+ );
311
+ yield* (yield* mcpClientEffect({ ...parsed, timeoutMs: yield* remaining })).check;
312
+ return yield* remaining.pipe(
313
+ Effect_exports.flatMap(
314
+ (timeoutMs2) => mcpClientEffect({ url: parsed.url, signal: parsed.signal, timeoutMs: timeoutMs2 })
315
+ ),
316
+ Effect_exports.flatMap((anonymous) => anonymous.check),
317
+ Effect_exports.matchEffect({
318
+ onSuccess: () => Effect_exports.fail(new McpCredentialsUnverified({ anonymous: "answered" })),
319
+ // Executor's network refused the attempt, so the server never answered it.
320
+ onFailure: (error) => Schema_exports.is(NetworkRefused)(error) ? Effect_exports.fail(error) : refusesCredentials(error) ? Effect_exports.void : Effect_exports.fail(new McpCredentialsUnverified({ anonymous: error }))
321
+ }),
322
+ Effect_exports.withSpan("provider.mcp.anonymous")
323
+ );
324
+ }).pipe(Effect_exports.withSpan("provider.mcp.health"));
219
325
  var mcpToolsEffect = (input) => mcpClientEffect(input).pipe(Effect_exports.flatMap(adaptMcpTools));
220
326
 
221
327
  export {
222
328
  mcpClientEffect,
329
+ mcpHealthEffect,
223
330
  mcpToolsEffect
224
331
  };
@@ -0,0 +1,92 @@
1
+ import {
2
+ JsonValue
3
+ } from "./chunk-FBBXFFFJ.js";
4
+ import {
5
+ HttpApiEndpoint_exports,
6
+ HttpApiGroup_exports,
7
+ HttpApiSchema_exports,
8
+ HttpApi_exports
9
+ } from "./chunk-QYM4STZW.js";
10
+ import {
11
+ Schema_exports
12
+ } from "./chunk-EXGKN554.js";
13
+
14
+ // src/contracts/ui.ts
15
+ var UiContext = Schema_exports.Struct({
16
+ deployment: Schema_exports.NonEmptyString,
17
+ profile: Schema_exports.optional(Schema_exports.NonEmptyString),
18
+ expectedProfileRevision: Schema_exports.optional(Schema_exports.Int)
19
+ });
20
+ var UiOperation = Schema_exports.Struct({
21
+ ...UiContext.fields,
22
+ name: Schema_exports.NonEmptyString,
23
+ input: JsonValue
24
+ });
25
+ var UiUnauthorized = class extends Schema_exports.TaggedError()(
26
+ "UiUnauthorized",
27
+ {},
28
+ { httpApiStatus: 401 }
29
+ ) {
30
+ };
31
+ var UiForbidden = class extends Schema_exports.TaggedError()(
32
+ "UiForbidden",
33
+ {},
34
+ { httpApiStatus: 403 }
35
+ ) {
36
+ };
37
+ var UiDeploymentChanged = class extends Schema_exports.TaggedError()(
38
+ "UiDeploymentChanged",
39
+ {},
40
+ { httpApiStatus: 409 }
41
+ ) {
42
+ };
43
+ var UiFailed = class extends Schema_exports.TaggedError()(
44
+ "UiFailed",
45
+ {
46
+ reason: Schema_exports.Literals(["unavailable", "operation_failed", "account_required"])
47
+ },
48
+ { httpApiStatus: 422 }
49
+ ) {
50
+ };
51
+ var UiSnapshot = Schema_exports.Union([
52
+ Schema_exports.Struct({
53
+ type: Schema_exports.Literal("snapshot"),
54
+ value: JsonValue,
55
+ trace: Schema_exports.optional(Schema_exports.Unknown)
56
+ }),
57
+ Schema_exports.Struct({ type: Schema_exports.Literal("failure"), error: UiFailed }),
58
+ Schema_exports.Struct({ type: Schema_exports.Literal("heartbeat") })
59
+ ]);
60
+ var errors = [UiUnauthorized, UiForbidden, UiDeploymentChanged, UiFailed];
61
+ var AppUiApi = HttpApi_exports.make("app-ui").add(
62
+ HttpApiGroup_exports.make("ui").add(
63
+ HttpApiEndpoint_exports.post("query", "/_executor/api/query", {
64
+ payload: UiOperation,
65
+ success: JsonValue,
66
+ error: errors
67
+ })
68
+ ).add(
69
+ HttpApiEndpoint_exports.post("mutate", "/_executor/api/mutate", {
70
+ payload: UiOperation,
71
+ success: JsonValue,
72
+ error: errors
73
+ })
74
+ ).add(
75
+ HttpApiEndpoint_exports.post("subscribe", "/_executor/api/subscribe", {
76
+ payload: UiOperation,
77
+ success: HttpApiSchema_exports.StreamSse({ data: UiSnapshot, error: Schema_exports.Union(errors) }),
78
+ error: errors
79
+ })
80
+ )
81
+ );
82
+
83
+ export {
84
+ UiContext,
85
+ UiOperation,
86
+ UiUnauthorized,
87
+ UiForbidden,
88
+ UiDeploymentChanged,
89
+ UiFailed,
90
+ UiSnapshot,
91
+ AppUiApi
92
+ };
@@ -1,6 +1,36 @@
1
1
  import {
2
+ SchemaGetter_exports,
2
3
  Schema_exports
3
- } from "./chunk-FW5HBOIK.js";
4
+ } from "./chunk-EXGKN554.js";
5
+
6
+ // ../utils/src/api-error.ts
7
+ var MessageField = Schema_exports.String.pipe(
8
+ Schema_exports.decodeTo(Schema_exports.optionalKey(Schema_exports.String), {
9
+ decode: SchemaGetter_exports.omit(),
10
+ encode: SchemaGetter_exports.passthrough()
11
+ })
12
+ );
13
+ function withFields(definition) {
14
+ const fields = definition.fields;
15
+ const message = definition.message;
16
+ const documentation = typeof message === "string" ? { description: message } : {};
17
+ const DefinedError = Schema_exports.Error(definition.tag)(
18
+ Schema_exports.TaggedStruct(definition.tag, { ...fields, message: MessageField }).annotate(
19
+ documentation
20
+ ),
21
+ { httpApiStatus: definition.status, ...documentation }
22
+ );
23
+ Object.defineProperty(DefinedError.prototype, "message", {
24
+ get() {
25
+ return typeof message === "string" ? message : message(this);
26
+ }
27
+ });
28
+ return DefinedError;
29
+ }
30
+ function define(definition) {
31
+ return "fields" in definition ? withFields(definition) : withFields({ ...definition, fields: {} });
32
+ }
33
+ var ApiError = { define };
4
34
 
5
35
  // src/contracts/skills.ts
6
36
  var SkillFilePath = Schema_exports.NonEmptyString.check(
@@ -45,9 +75,18 @@ var AppSkillSource = Schema_exports.Struct({
45
75
  )
46
76
  )
47
77
  });
48
- var SkillDefinitionInvalid = class extends Schema_exports.TaggedError()(
49
- "SkillDefinitionInvalid",
50
- {
78
+ var skillDefinitionFailures = {
79
+ files: (file) => `The skill files of \u201C${file}\u201D are invalid: each needs a unique relative path, text content and a SKILL.md document.`,
80
+ directory: (file) => `\u201C${file}\u201D is not a valid skill directory. Skill directory names use lowercase letters and digits separated by single hyphens.`,
81
+ "missing-document": (file) => `\u201C${file}\u201D is missing.`,
82
+ frontmatter: (file) => `\u201C${file}\u201D must start with valid YAML frontmatter between --- lines.`,
83
+ metadata: (file) => `The frontmatter of \u201C${file}\u201D needs a valid name and description within the Agent Skills limits.`,
84
+ "name-mismatch": (file) => `The name in \u201C${file}\u201D does not match its skill directory.`
85
+ };
86
+ var SkillDefinitionInvalid = ApiError.define({
87
+ tag: "SkillDefinitionInvalid",
88
+ status: 400,
89
+ fields: {
51
90
  file: SkillFilePath,
52
91
  reason: Schema_exports.Literals([
53
92
  "files",
@@ -58,9 +97,8 @@ var SkillDefinitionInvalid = class extends Schema_exports.TaggedError()(
58
97
  "name-mismatch"
59
98
  ])
60
99
  },
61
- { httpApiStatus: 400 }
62
- ) {
63
- };
100
+ message: ({ file, reason }) => skillDefinitionFailures[reason](file)
101
+ });
64
102
  var AppSkills = Schema_exports.Array(AppSkillSource).check(
65
103
  Schema_exports.makeFilter((skills) => new Set(skills.map((skill) => skill.name)).size === skills.length)
66
104
  );
@@ -4,7 +4,7 @@ import {
4
4
  fromWeb,
5
5
  layerMergedContext,
6
6
  make2 as make
7
- } from "./chunk-QKHR7BMF.js";
7
+ } from "./chunk-CJY5X26R.js";
8
8
  import {
9
9
  Reference,
10
10
  Service,
@@ -17,7 +17,7 @@ import {
17
17
  succeed4 as succeed,
18
18
  toReadableStreamEffect,
19
19
  tryPromise
20
- } from "./chunk-FW5HBOIK.js";
20
+ } from "./chunk-EXGKN554.js";
21
21
  import {
22
22
  __export
23
23
  } from "./chunk-CZ7CSFO4.js";