apps 0.0.1-beta.1 → 0.0.1-beta.100

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 (211) hide show
  1. package/README.md +112 -72
  2. package/framework-reference.json +1 -1
  3. package/js/browser-XIPJGLH2.js +65 -0
  4. package/js/chunk-2CURR5Y7.js +264 -0
  5. package/js/chunk-2LSGC7XY.js +42 -0
  6. package/js/{chunk-YEJOQEII.js → chunk-4PIQKACY.js} +65 -10
  7. package/js/chunk-4UPC36ZL.js +5185 -0
  8. package/js/{chunk-4LPG6RCH.js → chunk-4X2UI4R2.js} +7 -27
  9. package/js/chunk-5C6RAGAS.js +335 -0
  10. package/js/chunk-62NVUKED.js +39 -0
  11. package/js/chunk-74H25C4X.js +95 -0
  12. package/js/chunk-7HG422GB.js +90 -0
  13. package/js/chunk-7STIP5CS.js +171 -0
  14. package/js/{chunk-QKHR7BMF.js → chunk-ACQXVKVQ.js} +87 -51
  15. package/js/{chunk-OHRT55C4.js → chunk-DILSCQPJ.js} +226 -265
  16. package/js/chunk-ILYCJ3HV.js +449 -0
  17. package/js/chunk-K6TSCYAO.js +712 -0
  18. package/js/{chunk-EVJUVWN2.js → chunk-KLSEU35Y.js} +463 -218
  19. package/js/chunk-OD3KFKZD.js +1617 -0
  20. package/js/chunk-OWN3DP2W.js +88 -0
  21. package/js/{chunk-ZTFQHGEB.js → chunk-PBGPES67.js} +3 -5
  22. package/js/chunk-QI66R4FP.js +786 -0
  23. package/js/chunk-RN4YB4JT.js +1922 -0
  24. package/js/{chunk-ZCAMUXSG.js → chunk-URKOTNDA.js} +795 -177
  25. package/js/{chunk-NCYXZN2G.js → chunk-UVL56Z6E.js} +390 -23
  26. package/js/{chunk-2HHMABB6.js → chunk-VAI3EVCS.js} +700 -78
  27. package/js/chunk-VCYWAA4N.js +49 -0
  28. package/js/{chunk-HDJH3RPR.js → chunk-YDW7DX3A.js} +4 -4
  29. package/js/chunk-YWVISRZD.js +268 -0
  30. package/js/{chunk-FW5HBOIK.js → chunk-ZKDXML77.js} +19272 -18299
  31. package/js/client.js +148 -100
  32. package/js/contracts.js +208 -24
  33. package/js/effect.js +18 -19
  34. package/js/es-DIULA3ZF.js +39371 -0
  35. package/js/graphql.js +62 -58
  36. package/js/host.js +83 -60
  37. package/js/index.js +381 -263
  38. package/js/mcp/effect.js +21 -21
  39. package/js/mcp.js +117 -74
  40. package/js/openapi.js +4613 -42691
  41. package/js/react.js +2 -3
  42. package/js/skills/effect.js +6 -4
  43. package/js/skills.js +233 -70
  44. package/js/storage/facet.js +1 -540
  45. package/js/ui/auth/contracts.js +8 -9
  46. package/js/ui/auth.js +16 -14
  47. package/js/ui/contracts.js +9 -8
  48. package/js/ui/serving.js +8609 -227
  49. package/package.json +3 -8
  50. package/runtime.json +1 -1
  51. package/types/app-cache/src/contracts/cache.d.ts +60 -2
  52. package/types/app-cache/src/index.d.ts +92 -2
  53. package/types/app-data/src/contracts/database.d.ts +33 -6
  54. package/types/apps/src/contracts/api-response-error.d.ts +4 -0
  55. package/types/apps/src/contracts/app.d.ts +63 -17
  56. package/types/apps/src/contracts/cache.d.ts +24 -1
  57. package/types/apps/src/contracts/context.d.ts +60 -17
  58. package/types/apps/src/contracts/elicitation.d.ts +23 -7
  59. package/types/apps/src/contracts/events.d.ts +94 -0
  60. package/types/apps/src/contracts/failure.d.ts +54 -0
  61. package/types/apps/src/contracts/graphql.d.ts +2 -1
  62. package/types/apps/src/contracts/host.d.ts +1325 -534
  63. package/types/apps/src/contracts/icons.d.ts +28 -0
  64. package/types/apps/src/contracts/live.d.ts +2 -0
  65. package/types/apps/src/contracts/mcp.d.ts +97 -20
  66. package/types/apps/src/contracts/network.d.ts +120 -0
  67. package/types/apps/src/contracts/openapi-compile.d.ts +82 -3
  68. package/types/apps/src/contracts/openapi-document.d.ts +1 -1
  69. package/types/apps/src/contracts/openapi.d.ts +51 -9
  70. package/types/apps/src/contracts/operations.d.ts +14 -12
  71. package/types/apps/src/contracts/placement.d.ts +102 -0
  72. package/types/apps/src/contracts/protocol-version.d.ts +6 -0
  73. package/types/apps/src/contracts/protocols/1.d.ts +2241 -0
  74. package/types/apps/src/contracts/protocols/10.d.ts +1450 -0
  75. package/types/apps/src/contracts/protocols/11.d.ts +1149 -0
  76. package/types/apps/src/contracts/protocols/12.d.ts +3310 -0
  77. package/types/apps/src/contracts/protocols/2.d.ts +711 -0
  78. package/types/apps/src/contracts/protocols/3.d.ts +776 -0
  79. package/types/apps/src/contracts/protocols/4.d.ts +1306 -0
  80. package/types/apps/src/contracts/protocols/5.d.ts +1200 -0
  81. package/types/apps/src/contracts/protocols/6.d.ts +1629 -0
  82. package/types/apps/src/contracts/protocols/7.d.ts +1785 -0
  83. package/types/apps/src/contracts/protocols/8.d.ts +1182 -0
  84. package/types/apps/src/contracts/protocols/9.d.ts +1104 -0
  85. package/types/apps/src/contracts/protocols/current.d.ts +6857 -0
  86. package/types/apps/src/contracts/protocols/oauth-6.d.ts +74 -0
  87. package/types/apps/src/contracts/protocols/oauth.d.ts +134 -0
  88. package/types/apps/src/contracts/provider-error.d.ts +9 -0
  89. package/types/apps/src/contracts/provider.d.ts +140 -10
  90. package/types/apps/src/contracts/router.d.ts +59 -0
  91. package/types/apps/src/contracts/schedules.d.ts +7 -1
  92. package/types/apps/src/contracts/schema.d.ts +21 -0
  93. package/types/apps/src/contracts/shared-catalog.d.ts +11 -0
  94. package/types/apps/src/contracts/skills.d.ts +60 -14
  95. package/types/apps/src/contracts/sql.d.ts +63 -0
  96. package/types/apps/src/contracts/ui-auth.d.ts +6 -14
  97. package/types/apps/src/contracts/ui.d.ts +70 -30
  98. package/types/apps/src/contracts/webhooks.d.ts +24 -7
  99. package/types/apps/src/contracts/workflows.d.ts +89 -36
  100. package/types/apps/src/facet.d.ts +4 -5
  101. package/types/apps/src/graphql.d.ts +1 -3
  102. package/types/apps/src/host.d.ts +5 -0
  103. package/types/apps/src/implementation/account-router.d.ts +13 -0
  104. package/types/apps/src/implementation/app.d.ts +44 -16
  105. package/types/apps/src/implementation/authoring.d.ts +25 -5
  106. package/types/apps/src/implementation/browser-scripts.gen.d.ts +6 -0
  107. package/types/apps/src/implementation/cache.d.ts +32 -3
  108. package/types/apps/src/implementation/catalog-cache.d.ts +43 -5
  109. package/types/apps/src/implementation/elicitation.d.ts +18 -15
  110. package/types/apps/src/implementation/events.d.ts +64 -0
  111. package/types/apps/src/implementation/failure-detail.d.ts +48 -0
  112. package/types/apps/src/implementation/graphql-catalog.d.ts +4 -7
  113. package/types/apps/src/implementation/graphql.d.ts +4 -3
  114. package/types/apps/src/implementation/input-problems.d.ts +6 -2
  115. package/types/apps/src/implementation/invocation-timing.d.ts +18 -0
  116. package/types/apps/src/implementation/live.d.ts +2 -2
  117. package/types/apps/src/implementation/mcp-call.d.ts +6 -5
  118. package/types/apps/src/implementation/mcp-catalog.d.ts +7 -8
  119. package/types/apps/src/implementation/mcp-client.d.ts +49 -25
  120. package/types/apps/src/implementation/mcp-tools.d.ts +2 -1
  121. package/types/apps/src/implementation/mcp.d.ts +52 -25
  122. package/types/apps/src/implementation/network.d.ts +16 -0
  123. package/types/apps/src/implementation/openapi-compile.d.ts +30 -8
  124. package/types/apps/src/implementation/openapi-document.d.ts +46 -21
  125. package/types/apps/src/implementation/openapi-names.d.ts +23 -0
  126. package/types/apps/src/implementation/openapi-request.d.ts +10 -3
  127. package/types/apps/src/implementation/openapi-source.d.ts +30 -8
  128. package/types/apps/src/implementation/openapi-upgrade.d.ts +4 -0
  129. package/types/apps/src/implementation/operations.d.ts +84 -10
  130. package/types/apps/src/implementation/optimistic.d.ts +1 -1
  131. package/types/apps/src/implementation/placement.d.ts +60 -0
  132. package/types/apps/src/implementation/protocol-operations.d.ts +6 -4
  133. package/types/apps/src/implementation/provider-error.d.ts +28 -1
  134. package/types/apps/src/implementation/provider.d.ts +26 -6
  135. package/types/apps/src/implementation/query-commit.d.ts +1 -1
  136. package/types/apps/src/implementation/router-catalog.d.ts +227 -0
  137. package/types/apps/src/implementation/router.d.ts +78 -0
  138. package/types/apps/src/implementation/runtime-yield.d.ts +7 -0
  139. package/types/apps/src/implementation/schedules.d.ts +39 -8
  140. package/types/apps/src/implementation/schema.d.ts +111 -15
  141. package/types/apps/src/implementation/skills.d.ts +18 -24
  142. package/types/apps/src/implementation/sql.d.ts +71 -0
  143. package/types/apps/src/implementation/swagger-client.d.ts +28 -0
  144. package/types/apps/src/implementation/ui-account-notice.d.ts +9 -0
  145. package/types/apps/src/implementation/ui-auth.d.ts +12 -6
  146. package/types/apps/src/implementation/ui-client.d.ts +3 -3
  147. package/types/apps/src/implementation/ui-document.d.ts +5 -0
  148. package/types/apps/src/implementation/ui-errors.d.ts +1 -1
  149. package/types/apps/src/implementation/ui-serving.d.ts +31 -12
  150. package/types/apps/src/implementation/ui-watch.d.ts +1 -1
  151. package/types/apps/src/implementation/upstream-error.d.ts +7 -0
  152. package/types/apps/src/implementation/webhooks.d.ts +15 -6
  153. package/types/apps/src/implementation/workflow-context.d.ts +17 -5
  154. package/types/apps/src/implementation/workflows.d.ts +11 -4
  155. package/types/apps/src/index.d.ts +71 -21
  156. package/types/apps/src/mcp.d.ts +25 -5
  157. package/types/apps/src/openapi.d.ts +11 -6
  158. package/types/apps/src/react.d.ts +1 -1
  159. package/types/apps/src/skills.d.ts +13 -8
  160. package/types/apps/src/ui-auth.d.ts +2 -2
  161. package/types/apps/src/ui-serving.d.ts +1 -1
  162. package/types/telemetry/src/app-records.d.ts +42 -0
  163. package/types/telemetry/src/browser-operations.d.ts +7 -4
  164. package/types/telemetry/src/browser.d.ts +8 -3
  165. package/types/telemetry/src/config.d.ts +2 -2
  166. package/types/telemetry/src/index.d.ts +2 -1
  167. package/types/telemetry/src/layer.d.ts +10 -4
  168. package/types/telemetry/src/measurements.d.ts +1 -1
  169. package/types/telemetry/src/ownership.d.ts +60 -0
  170. package/types/telemetry/src/recorded-failure.d.ts +29 -0
  171. package/types/telemetry/src/relay.d.ts +16 -6
  172. package/types/telemetry/src/span-attributes.d.ts +17 -1
  173. package/types/telemetry/src/transport.d.ts +8 -1
  174. package/types/utils/src/api-error.d.ts +55 -0
  175. package/types/utils/src/connection-failure.d.ts +33 -0
  176. package/types/utils/src/legacy-keys.d.ts +20 -0
  177. package/types/utils/src/recorded-message.d.ts +18 -0
  178. package/types/utils/src/schema-definitions.d.ts +13 -0
  179. package/types/utils/src/user-facing-error.d.ts +83 -0
  180. package/js/chunk-6IIO4NPI.js +0 -29
  181. package/js/chunk-6YBRWRK3.js +0 -160
  182. package/js/chunk-BMOIAIVR.js +0 -138
  183. package/js/chunk-FZJOYIZO.js +0 -19
  184. package/js/chunk-G7IE6BKC.js +0 -224
  185. package/js/chunk-IHQ4ML7K.js +0 -2193
  186. package/js/chunk-KOXMLKTM.js +0 -1288
  187. package/js/chunk-M6ZRRIBI.js +0 -877
  188. package/js/chunk-PLCMJREA.js +0 -590
  189. package/js/chunk-PZ36XMXW.js +0 -93
  190. package/js/chunk-RBAC33PQ.js +0 -267
  191. package/js/chunk-SATWJKN6.js +0 -34
  192. package/js/chunk-SWPD52J7.js +0 -35
  193. package/js/chunk-TE4KO4HI.js +0 -47
  194. package/js/chunk-W7D7WVSY.js +0 -18
  195. package/js/chunk-X7SFGU4Q.js +0 -280
  196. package/js/chunk-ZJWDMTE3.js +0 -63
  197. package/js/mcp/stdio.js +0 -128
  198. package/types/app-data/src/implementation/cursor.d.ts +0 -10
  199. package/types/app-data/src/implementation/index-key.d.ts +0 -7
  200. package/types/app-data/src/implementation/promise.d.ts +0 -68
  201. package/types/app-data/src/implementation/range.d.ts +0 -8
  202. package/types/app-data/src/implementation/schema.d.ts +0 -33
  203. package/types/app-data/src/implementation/sqlite.d.ts +0 -11
  204. package/types/app-data/src/index.d.ts +0 -4
  205. package/types/apps/src/contracts/dynamic-tools.d.ts +0 -13
  206. package/types/apps/src/contracts/storage.d.ts +0 -68
  207. package/types/apps/src/implementation/account-operations.d.ts +0 -151
  208. package/types/apps/src/implementation/dynamic-tools.d.ts +0 -8
  209. package/types/apps/src/implementation/mcp-stdio.d.ts +0 -4
  210. package/types/apps/src/implementation/storage.d.ts +0 -13
  211. package/types/apps/src/mcp-stdio.d.ts +0 -8
package/js/index.js CHANGED
@@ -1,93 +1,95 @@
1
1
  import {
2
- CacheError,
2
+ ResponseDecodeError,
3
+ ResponseStatusError,
4
+ base64,
5
+ basic,
6
+ bearer,
7
+ declarePlacements,
3
8
  defineApp,
4
- defineDatabase,
5
- table,
9
+ event,
10
+ header,
11
+ query,
12
+ t,
6
13
  workflow
7
- } from "./chunk-RBAC33PQ.js";
8
- import "./chunk-PLCMJREA.js";
14
+ } from "./chunk-ILYCJ3HV.js";
9
15
  import {
10
- fromPromise,
16
+ dynamicRouter,
11
17
  mutation,
12
18
  nativeOperation,
19
+ nativeRouter,
13
20
  operationDeclaration,
14
- query,
15
- withApproval
16
- } from "./chunk-PZ36XMXW.js";
21
+ query as query2,
22
+ renameTools,
23
+ router,
24
+ routerDeclaration,
25
+ toolAnnotations,
26
+ withApproval,
27
+ withApprovals
28
+ } from "./chunk-2CURR5Y7.js";
17
29
  import {
18
- accountProviderError
19
- } from "./chunk-ZJWDMTE3.js";
30
+ accountProviderError,
31
+ fromPromise
32
+ } from "./chunk-7STIP5CS.js";
20
33
  import {
34
+ CacheError,
21
35
  CalendarSchedule,
22
36
  ElicitationFailed,
37
+ FetchOptionUnsupported,
23
38
  HostedTool,
24
39
  HostedToolSummary,
25
40
  Interval,
41
+ NetworkRefused,
26
42
  NonRetryableError,
27
43
  OAuth2AccessToken,
28
44
  OAuth2Config,
29
45
  OAuth2Method,
30
46
  Provider,
47
+ ProviderError,
31
48
  ScheduleTiming,
32
49
  SecretsMethod,
33
50
  WorkflowFailure
34
- } from "./chunk-IHQ4ML7K.js";
35
- import "./chunk-BMOIAIVR.js";
36
- import "./chunk-YEJOQEII.js";
37
- import "./chunk-SWPD52J7.js";
38
- import {
39
- ProviderError
40
- } from "./chunk-W7D7WVSY.js";
51
+ } from "./chunk-4UPC36ZL.js";
52
+ import "./chunk-4PIQKACY.js";
41
53
  import {
42
54
  array,
43
55
  boolean,
56
+ combineJsonSchemas,
44
57
  decoderOf,
45
- id,
58
+ fieldExposure,
46
59
  importedJsonSchema,
60
+ isSchema,
47
61
  json,
48
62
  jsonSchema,
49
63
  literal,
50
- nestJsonSchema,
51
64
  number,
52
65
  object,
53
66
  once,
54
67
  parse,
68
+ parseDeclaration,
69
+ plain,
70
+ raw,
55
71
  record,
56
72
  string,
57
- userId,
58
73
  withLazyJsonSchemaDocument,
59
74
  wrap
60
- } from "./chunk-2HHMABB6.js";
61
- import "./chunk-FZJOYIZO.js";
75
+ } from "./chunk-VAI3EVCS.js";
76
+ import "./chunk-URKOTNDA.js";
77
+ import "./chunk-YDW7DX3A.js";
78
+ import "./chunk-OWN3DP2W.js";
62
79
  import {
80
+ DeclarationInvalid,
63
81
  JsonObject,
64
82
  JsonValue,
65
83
  ValidationError
66
- } from "./chunk-SATWJKN6.js";
84
+ } from "./chunk-7HG422GB.js";
85
+ import "./chunk-DILSCQPJ.js";
86
+ import "./chunk-ACQXVKVQ.js";
67
87
  import {
68
88
  Effect_exports,
69
89
  Schema_exports
70
- } from "./chunk-FW5HBOIK.js";
90
+ } from "./chunk-ZKDXML77.js";
71
91
  import "./chunk-CZ7CSFO4.js";
72
92
 
73
- // src/contracts/http.ts
74
- var ResponseStatusError = class extends Schema_exports.TaggedError()(
75
- "ResponseStatusError",
76
- { status: Schema_exports.Number }
77
- ) {
78
- get message() {
79
- return `Request failed with status ${this.status}`;
80
- }
81
- };
82
- var ResponseDecodeError = class extends Schema_exports.TaggedError()(
83
- "ResponseDecodeError",
84
- {}
85
- ) {
86
- get message() {
87
- return "Response body did not match the expected schema";
88
- }
89
- };
90
-
91
93
  // src/implementation/http.ts
92
94
  var decodeJson = (response, schema) => Effect_exports.gen(function* () {
93
95
  if (response.status < 200 || response.status >= 300) {
@@ -99,86 +101,145 @@ var decodeJson = (response, schema) => Effect_exports.gen(function* () {
99
101
 
100
102
  // src/implementation/provider.ts
101
103
  var secrets = (options) => new SecretsMethod(options);
102
- var oauth2 = (config, response) => parse(OAuth2Config, config).pipe(Effect_exports.map((config2) => new OAuth2Method({ config: config2, response })));
103
- var defineProvider = (options) => new Provider(options);
104
+ var clientCredentials = Schema_exports.is(Schema_exports.Struct({ grant: Schema_exports.Literal("client_credentials") }));
105
+ var oauth2Form = (config) => {
106
+ const [discovered, declared, discoveredMachine, declaredMachine] = OAuth2Config.members;
107
+ const discovers = typeof config === "object" && config !== null && Object.hasOwn(config, "discover");
108
+ if (clientCredentials(config)) return discovers ? discoveredMachine : declaredMachine;
109
+ return discovers ? discovered : declared;
110
+ };
111
+ var oauth2 = (config, response, exposure, request) => parseDeclaration(OAuth2Config, config, "oauth2()", oauth2Form).pipe(
112
+ Effect_exports.map(
113
+ (config2) => new OAuth2Method({
114
+ config: config2,
115
+ response,
116
+ ...exposure === void 0 ? {} : { exposure },
117
+ ...request === void 0 ? {} : { request }
118
+ })
119
+ )
120
+ );
121
+ var defineProvider = ({
122
+ health,
123
+ ...options
124
+ }) => {
125
+ const placed = Object.entries(options.auth).filter(([, method]) => method.request !== void 0);
126
+ if (options.hosts === void 0 && placed.length > 0)
127
+ throw new TypeError(
128
+ `Provider "${options.name}" declares a request for ${placed.map(([name]) => name).join(", ")} but no hosts. Declare the hosts its credentials may be sent to.`
129
+ );
130
+ if (health === void 0) return new Provider(options);
131
+ const run = fromPromise(health, "check");
132
+ return new Provider({ ...options, health: { run } });
133
+ };
104
134
 
105
- // src/implementation/account-operations.ts
106
- var inputDocument = (operation) => {
107
- const imported = importedJsonSchema(operation.input);
135
+ // src/implementation/account-router.ts
136
+ var decoderDocument = (decoder) => {
137
+ const imported = importedJsonSchema(decoder);
108
138
  if (imported !== void 0) return Schema_exports.decodeUnknownSync(JsonObject)(imported);
109
- const document = Schema_exports.toJsonSchemaDocument(operation.input);
139
+ const document = Schema_exports.toJsonSchemaDocument(decoder);
110
140
  return Schema_exports.decodeUnknownSync(JsonObject)({ ...document.schema, $defs: document.definitions });
111
141
  };
142
+ var accountBranches = (variants) => {
143
+ const groups = /* @__PURE__ */ new Map();
144
+ for (const [accountId, schema] of variants) {
145
+ const key = JSON.stringify(schema);
146
+ const group = groups.get(key);
147
+ if (group === void 0) groups.set(key, { schema, first: accountId, rest: [] });
148
+ else group.rest.push(accountId);
149
+ }
150
+ const branches = [...groups.values()];
151
+ const { $defs, schemas } = combineJsonSchemas(
152
+ branches.map(({ schema }) => schema),
153
+ (index) => `#/anyOf/${index}/properties/input`
154
+ );
155
+ return {
156
+ type: "object",
157
+ ...$defs === void 0 ? {} : { $defs },
158
+ anyOf: schemas.map((input, index) => {
159
+ const { first, rest } = branches[index];
160
+ return {
161
+ type: "object",
162
+ properties: {
163
+ accountId: rest.length === 0 ? { type: "string", const: first } : { type: "string", enum: [first, ...rest] },
164
+ input
165
+ },
166
+ required: ["accountId", "input"]
167
+ };
168
+ })
169
+ };
170
+ };
171
+ var outputBranches = (outputs) => {
172
+ const { $defs, schemas } = combineJsonSchemas(
173
+ [...new Map(outputs.map((output) => [JSON.stringify(output), output])).values()],
174
+ (index) => `#/anyOf/${index}`
175
+ );
176
+ return { ...$defs === void 0 ? {} : { $defs }, anyOf: schemas };
177
+ };
112
178
  var declaresOutput = (operation) => {
179
+ if (operation.output !== void 0) return true;
113
180
  const property = Object.getOwnPropertyDescriptor(operation, "outputSchema");
114
181
  return property !== void 0 && (property.get !== void 0 || property.value !== void 0);
115
182
  };
116
- var combine = (kind, groups) => Object.fromEntries(
117
- [...groups].map(([name, accounts]) => {
118
- const variants = [...accounts.values()];
119
- const first = variants[0];
120
- if (first === void 0)
121
- throw new Error("An account operation must have at least one account");
122
- const select = (input2) => {
123
- const operation = accounts.get(input2.accountId);
124
- if (operation === void 0)
125
- throw new Error("Account selection must be decoded before execution");
126
- return operation;
127
- };
128
- const input = Schema_exports.Union(
129
- [...accounts].map(
130
- ([accountId, operation]) => Schema_exports.Struct({ accountId: Schema_exports.Literal(accountId), input: operation.input })
183
+ var outputDocument = (operation) => operation.output === void 0 ? operation.outputSchema : decoderDocument(operation.output);
184
+ var combineOperation = (accounts) => {
185
+ const variants = [...accounts.values()];
186
+ const first = variants[0];
187
+ if (first === void 0) throw new Error("An account operation must have at least one account");
188
+ const kind = variants.every((operation) => operation.kind === "query") ? "query" : "mutation";
189
+ const select = (input2) => {
190
+ const operation = accounts.get(input2.accountId);
191
+ if (operation === void 0)
192
+ throw new Error("Account selection must be decoded before execution");
193
+ return operation;
194
+ };
195
+ const input = Schema_exports.Union(
196
+ [...accounts].map(
197
+ ([accountId, operation]) => Schema_exports.Struct({ accountId: Schema_exports.Literal(accountId), input: operation.input })
198
+ )
199
+ );
200
+ const inputSchema = () => accountBranches(
201
+ [...accounts].map(([accountId, operation]) => [accountId, decoderDocument(operation.input)])
202
+ );
203
+ const declaration2 = operationDeclaration({
204
+ kind,
205
+ ...first.description === void 0 ? {} : { description: first.description },
206
+ ...first.title === void 0 ? {} : { title: first.title },
207
+ ...first.annotations === void 0 || !variants.every(
208
+ (operation) => JSON.stringify(operation.annotations) === JSON.stringify(first.annotations)
209
+ ) ? {} : { annotations: first.annotations },
210
+ ...first._meta === void 0 || !variants.every((operation) => JSON.stringify(operation._meta) === JSON.stringify(first._meta)) ? {} : { _meta: first._meta },
211
+ input: withLazyJsonSchemaDocument(input, inputSchema),
212
+ approval: (context) => {
213
+ const operation = select(context.toolInput);
214
+ return operation.approval === void 0 ? Effect_exports.succeed("approved") : operation.approval({ ...context, toolInput: context.toolInput.input });
215
+ },
216
+ run: (context, input2) => {
217
+ const operation = select(input2);
218
+ return operation.run(context, input2.input).pipe(
219
+ Effect_exports.mapError((error) => accountProviderError(error, input2.accountId)),
220
+ Effect_exports.flatMap(
221
+ (output) => operation.output === void 0 ? Effect_exports.succeed(output) : Schema_exports.decodeUnknownEffect(operation.output)(output)
222
+ )
223
+ );
224
+ }
225
+ });
226
+ if (variants.every(declaresOutput)) {
227
+ const outputSchema = once(
228
+ () => outputBranches(
229
+ variants.flatMap((operation) => {
230
+ const output = outputDocument(operation);
231
+ return output === void 0 ? [] : [output];
232
+ })
131
233
  )
132
234
  );
133
- const inputSchema = () => ({
134
- type: "object",
135
- anyOf: [...accounts].map(([accountId, operation], index) => ({
136
- type: "object",
137
- properties: {
138
- accountId: { type: "string", const: accountId },
139
- input: nestJsonSchema(inputDocument(operation), `#/anyOf/${index}/properties/input`)
140
- },
141
- required: ["accountId", "input"]
142
- }))
143
- });
144
- const declaration2 = operationDeclaration({
145
- kind,
146
- ...first.description === void 0 ? {} : { description: first.description },
147
- ...first.title === void 0 ? {} : { title: first.title },
148
- ...first.annotations === void 0 || !variants.every(
149
- (operation) => JSON.stringify(operation.annotations) === JSON.stringify(first.annotations)
150
- ) ? {} : { annotations: first.annotations },
151
- ...first._meta === void 0 || !variants.every(
152
- (operation) => JSON.stringify(operation._meta) === JSON.stringify(first._meta)
153
- ) ? {} : { _meta: first._meta },
154
- input: withLazyJsonSchemaDocument(input, inputSchema),
155
- approval: (context) => {
156
- const operation = select(context.toolInput);
157
- return operation.approval === void 0 ? Effect_exports.succeed("approved") : operation.approval({ ...context, toolInput: context.toolInput.input });
158
- },
159
- run: (context, input2) => {
160
- const operation = select(input2);
161
- return operation.run(context, input2.input).pipe(
162
- Effect_exports.mapError((error) => accountProviderError(error, input2.accountId)),
163
- Effect_exports.flatMap(
164
- (output) => operation.output === void 0 ? Effect_exports.succeed(output) : Schema_exports.decodeUnknownEffect(operation.output)(output)
165
- )
166
- );
167
- }
168
- });
169
- if (variants.every(declaresOutput)) {
170
- const outputSchema = once(() => ({
171
- anyOf: variants.flatMap(
172
- (operation) => operation.outputSchema === void 0 ? [] : [operation.outputSchema]
173
- ).map((output, index) => nestJsonSchema(output, `#/anyOf/${index}`))
174
- }));
175
- const native = nativeOperation(declaration2);
176
- if (native !== void 0)
177
- Object.defineProperty(native, "outputSchema", { enumerable: true, get: outputSchema });
178
- }
179
- return [name, declaration2];
180
- })
181
- );
235
+ const native2 = nativeOperation(declaration2);
236
+ if (native2 !== void 0)
237
+ Object.defineProperty(native2, "outputSchema", { enumerable: true, get: outputSchema });
238
+ }
239
+ const native = nativeOperation(declaration2);
240
+ if (native === void 0) throw new Error("Expected a combined operation");
241
+ return native;
242
+ };
182
243
  var sameAcross = (key, variants) => {
183
244
  const first = variants[0]?.[1][key];
184
245
  return first !== void 0 && variants.every(([, tool]) => JSON.stringify(tool[key]) === JSON.stringify(first)) ? { [key]: first } : {};
@@ -190,141 +251,144 @@ var mergeSummary = (name, variants) => {
190
251
  name,
191
252
  description: first.description,
192
253
  ...first.title === void 0 ? {} : { title: first.title },
193
- readOnly: name.startsWith("queries."),
254
+ readOnly: variants.every(([, tool]) => tool.readOnly === true),
194
255
  ...sameAcross("annotations", variants)
195
256
  });
196
257
  };
197
258
  var merge = (name, variants) => Schema_exports.decodeUnknownSync(HostedTool)({
198
259
  ...mergeSummary(name, variants),
199
- inputSchema: {
200
- type: "object",
201
- anyOf: variants.map(([accountId, tool], index) => ({
202
- type: "object",
203
- properties: {
204
- accountId: { type: "string", const: accountId },
205
- input: nestJsonSchema(tool.inputSchema, `#/anyOf/${index}/properties/input`)
206
- },
207
- required: ["accountId", "input"]
208
- }))
209
- },
260
+ inputSchema: accountBranches(
261
+ variants.map(([accountId, tool]) => [accountId, tool.inputSchema])
262
+ ),
210
263
  ...variants.every(([, tool]) => tool.outputSchema !== void 0) ? {
211
- outputSchema: {
212
- anyOf: variants.flatMap(
213
- ([, tool], index) => tool.outputSchema === void 0 ? [] : [nestJsonSchema(tool.outputSchema, `#/anyOf/${index}`)]
264
+ outputSchema: outputBranches(
265
+ variants.flatMap(
266
+ ([, tool]) => tool.outputSchema === void 0 ? [] : [tool.outputSchema]
214
267
  )
215
- }
268
+ )
216
269
  } : {},
217
270
  ...sameAcross("_meta", variants)
218
271
  });
219
- var accountOperations = (accounts, discover, options) => Effect_exports.runPromise(
272
+ var combineDynamic = (sources) => {
273
+ const first = [...sources.values()][0];
274
+ const grouped = (read) => Effect_exports.gen(function* () {
275
+ const groups = /* @__PURE__ */ new Map();
276
+ for (const [accountId, source] of sources) {
277
+ const tools = yield* read(source).pipe(
278
+ Effect_exports.mapError((error) => accountProviderError(error, accountId))
279
+ );
280
+ for (const tool of tools) {
281
+ const variants = groups.get(tool.name) ?? [];
282
+ if (variants.some(([id]) => id === accountId))
283
+ return yield* Effect_exports.die(new Error("Duplicate source operation"));
284
+ variants.push([accountId, tool]);
285
+ groups.set(tool.name, variants);
286
+ }
287
+ }
288
+ return groups;
289
+ });
290
+ return {
291
+ kind: "dynamic",
292
+ // Accounts share one source, so the first account describes the router.
293
+ ...first?.meta === void 0 ? {} : { meta: first.meta },
294
+ ...first?.overrides === void 0 ? {} : { overrides: first.overrides },
295
+ list: () => grouped((source) => source.list()).pipe(
296
+ Effect_exports.map((groups) => [...groups].map(([name, variants]) => merge(name, variants)))
297
+ ),
298
+ summaries: () => grouped(
299
+ (source) => source.summaries === void 0 ? source.list() : source.summaries()
300
+ ).pipe(
301
+ Effect_exports.map((groups) => [...groups].map(([name, variants]) => mergeSummary(name, variants)))
302
+ ),
303
+ describe: (name) => Effect_exports.gen(function* () {
304
+ const variants = [];
305
+ for (const [accountId, source] of sources) {
306
+ const tool = yield* (source.describe === void 0 ? source.list().pipe(Effect_exports.map((tools) => tools.find((tool2) => tool2.name === name))) : source.describe(name)).pipe(Effect_exports.mapError((error) => accountProviderError(error, accountId)));
307
+ if (tool !== void 0) variants.push([accountId, tool]);
308
+ }
309
+ return variants.length === 0 ? void 0 : merge(name, variants);
310
+ }),
311
+ resolve: (name) => Effect_exports.gen(function* () {
312
+ const operations = /* @__PURE__ */ new Map();
313
+ for (const [accountId, source] of sources) {
314
+ const operation = yield* source.resolve(name).pipe(Effect_exports.mapError((error) => accountProviderError(error, accountId)));
315
+ if (operation !== void 0) operations.set(accountId, operation);
316
+ }
317
+ return operations.size === 0 ? void 0 : combineOperation(operations);
318
+ })
319
+ };
320
+ };
321
+ var combineNode = (variants) => {
322
+ const nodes = [...variants.values()];
323
+ const first = nodes[0];
324
+ if (first === void 0) throw new Error("An account operation must have at least one account");
325
+ switch (first.kind) {
326
+ case "query":
327
+ case "mutation":
328
+ return combineOperation(
329
+ narrow(
330
+ variants,
331
+ (node) => node.kind === "query" || node.kind === "mutation"
332
+ )
333
+ );
334
+ case "dynamic":
335
+ return combineDynamic(
336
+ narrow(variants, (node) => node.kind === "dynamic")
337
+ );
338
+ case "router": {
339
+ const routers = narrow(variants, (node) => node.kind === "router");
340
+ const keys = new Set([...routers.values()].flatMap((router2) => Object.keys(router2.children)));
341
+ return {
342
+ kind: "router",
343
+ ...first.meta === void 0 ? {} : { meta: first.meta },
344
+ children: Object.fromEntries(
345
+ [...keys].map((key) => {
346
+ const children = /* @__PURE__ */ new Map();
347
+ for (const [accountId, router2] of routers) {
348
+ const child = Object.hasOwn(router2.children, key) ? router2.children[key] : void 0;
349
+ if (child !== void 0) children.set(accountId, child);
350
+ }
351
+ return [key, combineNode(children)];
352
+ })
353
+ )
354
+ };
355
+ }
356
+ }
357
+ };
358
+ var narrow = (variants, is) => {
359
+ const narrowed = /* @__PURE__ */ new Map();
360
+ for (const [accountId, node] of variants) {
361
+ if (!is(node)) throw new Error("Each account's router must have the same shape");
362
+ narrowed.set(accountId, node);
363
+ }
364
+ return narrowed;
365
+ };
366
+ var accountRouter = (accounts, discover, options) => Effect_exports.runPromise(
220
367
  Effect_exports.gen(function* () {
221
- const queries = /* @__PURE__ */ new Map();
222
- const mutations = /* @__PURE__ */ new Map();
223
- const sources = /* @__PURE__ */ new Map();
368
+ const routers = /* @__PURE__ */ new Map();
224
369
  for (const account of accounts) {
225
- const operations = yield* Effect_exports.tryPromise({
226
- try: () => discover(account),
370
+ const declaration2 = yield* Effect_exports.tryPromise({
371
+ try: async () => discover(account),
227
372
  catch: (error) => accountProviderError(error, account.id)
228
373
  });
229
- if (sources.has(account.id))
374
+ if (routers.has(account.id))
230
375
  return yield* Effect_exports.die(new Error("Account selections must be unique"));
231
- if (operations.dynamicTools !== void 0) sources.set(account.id, operations.dynamicTools);
232
- for (const [source, target] of [
233
- [operations.queries, queries],
234
- [operations.mutations, mutations]
235
- ]) {
236
- for (const [name, declaration2] of Object.entries(source ?? {})) {
237
- const operation = nativeOperation(declaration2);
238
- if (operation === void 0)
239
- return yield* Effect_exports.die(new Error("Expected a protocol operation"));
240
- const group = target.get(name) ?? /* @__PURE__ */ new Map();
241
- if (group.has(account.id))
242
- return yield* Effect_exports.die(new Error("Account selections must be unique"));
243
- group.set(account.id, operation);
244
- target.set(name, group);
245
- }
246
- }
376
+ const router2 = nativeRouter(declaration2);
377
+ if (router2 === void 0) return yield* Effect_exports.die(new Error("Expected a protocol router"));
378
+ routers.set(account.id, router2);
247
379
  }
248
- const declared = {
249
- queries: combine("query", queries),
250
- mutations: combine("mutation", mutations)
251
- };
252
- if (sources.size === 0) return declared;
253
- const grouped = (read) => Effect_exports.gen(function* () {
254
- const groups = /* @__PURE__ */ new Map();
255
- for (const [accountId, source] of sources) {
256
- const tools = yield* read(source).pipe(
257
- Effect_exports.mapError((error) => accountProviderError(error, accountId))
258
- );
259
- for (const tool of tools) {
260
- const variants = groups.get(tool.name) ?? [];
261
- if (variants.some(([id2]) => id2 === accountId))
262
- return yield* Effect_exports.die(new Error("Duplicate source operation"));
263
- variants.push([accountId, tool]);
264
- groups.set(tool.name, variants);
265
- }
266
- }
267
- return groups;
268
- });
269
- return {
270
- ...declared,
271
- dynamicTools: {
272
- list: () => grouped((source) => source.list()).pipe(
273
- Effect_exports.map((groups) => [...groups].map(([name, variants]) => merge(name, variants)))
274
- ),
275
- summaries: () => grouped(
276
- (source) => source.summaries === void 0 ? source.list() : source.summaries()
277
- ).pipe(
278
- Effect_exports.map(
279
- (groups) => [...groups].map(([name, variants]) => mergeSummary(name, variants))
280
- )
281
- ),
282
- describe: (name) => Effect_exports.gen(function* () {
283
- const variants = [];
284
- for (const [accountId, source] of sources) {
285
- const tool = yield* (source.describe === void 0 ? source.list().pipe(Effect_exports.map((tools) => tools.find((tool2) => tool2.name === name))) : source.describe(name)).pipe(Effect_exports.mapError((error) => accountProviderError(error, accountId)));
286
- if (tool !== void 0) variants.push([accountId, tool]);
287
- }
288
- return variants.length === 0 ? void 0 : merge(name, variants);
289
- }),
290
- resolve: (name) => Effect_exports.gen(function* () {
291
- const kind = name.startsWith("queries.") ? "query" : "mutation";
292
- const operations = /* @__PURE__ */ new Map();
293
- for (const [accountId, source] of sources) {
294
- const operation = yield* source.resolve(name).pipe(Effect_exports.mapError((error) => accountProviderError(error, accountId)));
295
- if (operation !== void 0) {
296
- if (operation.kind !== kind)
297
- return yield* Effect_exports.die(new Error("Operation kind changed"));
298
- operations.set(accountId, operation);
299
- }
300
- }
301
- if (operations.size === 0) return void 0;
302
- return nativeOperation(combine(kind, /* @__PURE__ */ new Map([[name, operations]]))[name]);
303
- })
304
- }
305
- };
380
+ if (routers.size === 0) return routerDeclaration({ kind: "router", children: {} });
381
+ const combined = combineNode(routers);
382
+ if (combined.kind !== "router" && combined.kind !== "dynamic")
383
+ return yield* Effect_exports.die(new Error("Expected a protocol router"));
384
+ return routerDeclaration(combined);
306
385
  }),
307
386
  options
308
387
  );
309
388
 
310
- // src/implementation/dynamic-tools.ts
311
- var dynamicTools = (source) => ({
312
- list: () => fromPromise(source.list)().pipe(
313
- Effect_exports.flatMap(Schema_exports.decodeUnknownEffect(Schema_exports.Array(HostedTool)))
314
- ),
315
- resolve: (name) => fromPromise(source.resolve)(name).pipe(
316
- Effect_exports.map((value) => {
317
- if (value === void 0) return void 0;
318
- const operation = nativeOperation(value);
319
- if (operation === void 0) throw new Error("Expected an operation declaration");
320
- return operation;
321
- })
322
- )
323
- });
324
-
325
389
  // src/implementation/dynamic-skills.ts
326
390
  var dynamicSkills = (source) => ({
327
- list: fromPromise(async () => source.list())
391
+ list: fromPromise(async () => source.list(), "skills")
328
392
  });
329
393
 
330
394
  // src/contracts/app.ts
@@ -334,58 +398,102 @@ var NotImplemented = class extends Schema_exports.TaggedError()("NotImplemented"
334
398
  };
335
399
 
336
400
  // src/implementation/schedules.ts
337
- var declaration = (timing, operation, input) => {
401
+ var declaration = (scope, timing, operation, input) => {
338
402
  const native = nativeOperation(operation);
339
403
  if (native === void 0 || native.kind !== "mutation")
340
404
  throw new Error("A schedule must reference a mutation");
405
+ if (scope === "app" && native.approval !== void 0)
406
+ throw new Error("An app schedule must reference a mutation without an approval");
341
407
  Schema_exports.decodeUnknownSync(native.input)(input);
342
- return { operation, timing, input: Schema_exports.decodeUnknownSync(JsonValue)(input) };
408
+ return { scope, operation, timing, input: Schema_exports.decodeUnknownSync(JsonValue)(input) };
343
409
  };
344
- var interval = (duration, operation, input) => {
410
+ var intervalTiming = (duration) => {
345
411
  const value = Schema_exports.decodeUnknownSync(Interval)(duration);
346
412
  const milliseconds = value.seconds !== void 0 ? value.seconds * 1e3 : value.minutes !== void 0 ? value.minutes * 6e4 : value.hours * 36e5;
347
- return declaration(
348
- Schema_exports.decodeUnknownSync(ScheduleTiming)({ kind: "interval", milliseconds }),
349
- operation,
350
- input
351
- );
413
+ return Schema_exports.decodeUnknownSync(ScheduleTiming)({ kind: "interval", milliseconds });
352
414
  };
353
- var cron = (calendar, operation, input) => declaration(
354
- {
355
- kind: "cron",
356
- calendar: Schema_exports.decodeUnknownSync(CalendarSchedule)({
357
- ...calendar,
358
- timezone: calendar.timezone ?? "UTC"
359
- })
360
- },
361
- operation,
362
- input
363
- );
415
+ var cronTiming = (calendar) => ({
416
+ kind: "cron",
417
+ calendar: Schema_exports.decodeUnknownSync(CalendarSchedule)({
418
+ ...calendar,
419
+ timezone: calendar.timezone ?? "UTC"
420
+ })
421
+ });
422
+ var userInterval = (duration, operation, input) => declaration("user", intervalTiming(duration), operation, input);
423
+ var userCron = (calendar, operation, input) => declaration("user", cronTiming(calendar), operation, input);
424
+ var appInterval = (duration, operation, input) => declaration("app", intervalTiming(duration), operation, input);
425
+ var appCron = (calendar, operation, input) => declaration("app", cronTiming(calendar), operation, input);
364
426
 
365
427
  // src/index.ts
428
+ var isFields = (value) => typeof value === "object" && value !== null && Object.values(value).every(isSchema);
429
+ var accountDecoder = (schema) => (
430
+ // SAFETY: the brand exists only in types; secret values are strings at runtime.
431
+ decoderOf(schema)
432
+ );
433
+ var exposureOf = (schema) => {
434
+ const marked = "fields" in schema && isFields(schema.fields) ? fieldExposure(schema.fields) : {};
435
+ return Object.keys(marked).length === 0 ? {} : { exposure: marked };
436
+ };
437
+ var fieldNames = (schema) => "fields" in schema && isFields(schema.fields) ? Object.keys(schema.fields) : schema === OAuth2AccessToken2 ? ["access_token"] : [];
438
+ var placementsOf = (method, schema, request) => request === void 0 ? {} : {
439
+ request: declarePlacements(
440
+ method,
441
+ fieldNames(schema),
442
+ exposureOf(schema).exposure,
443
+ request
444
+ )
445
+ };
366
446
  var OAuth2AccessToken2 = wrap(OAuth2AccessToken, false);
367
- var secrets2 = (options) => secrets({ label: options.label, fields: decoderOf(options.fields) });
447
+ var secrets2 = (options) => secrets({
448
+ label: options.label,
449
+ fields: accountDecoder(options.fields),
450
+ ...exposureOf(options.fields),
451
+ // SAFETY: the callback receives references named by the schema's own keys.
452
+ ...placementsOf(
453
+ `"${options.label}"`,
454
+ options.fields,
455
+ options.request
456
+ )
457
+ });
368
458
  function oauth22(options) {
369
- const { response = OAuth2AccessToken2, ...config } = options;
370
- return Effect_exports.runSync(oauth2(config, decoderOf(response)));
459
+ const { response = OAuth2AccessToken2, request, ...config } = options;
460
+ return Effect_exports.runSync(
461
+ oauth2(
462
+ config,
463
+ accountDecoder(response),
464
+ exposureOf(response).exposure,
465
+ // SAFETY: the callback receives references named by the response projection's own keys.
466
+ placementsOf("OAuth", response, request).request
467
+ )
468
+ );
371
469
  }
372
470
  var decodeJson2 = (response, schema) => {
373
471
  const native = {
374
472
  status: response.status,
375
- json: () => Effect_exports.tryPromise({
376
- try: () => response.json(),
377
- catch: (error) => error
378
- }).pipe(
379
- Effect_exports.catch(
380
- (error) => error instanceof SyntaxError ? Effect_exports.fail(new ResponseDecodeError()) : Effect_exports.die(error)
473
+ json: () => (
474
+ // oxlint-disable-next-line executor/authored-code-through-adapter -- a Response the app passes from its own code
475
+ Effect_exports.tryPromise({
476
+ try: () => response.json(),
477
+ catch: (error) => error
478
+ }).pipe(
479
+ Effect_exports.catch(
480
+ (error) => error instanceof SyntaxError ? Effect_exports.fail(new ResponseDecodeError()) : Effect_exports.die(error)
481
+ )
381
482
  )
382
483
  )
383
484
  };
384
485
  return Effect_exports.runPromise(decodeJson(native, decoderOf(schema)));
385
486
  };
487
+ function query3(first, second) {
488
+ if (typeof first === "string") return query(first, second);
489
+ return query2(...[first, second]);
490
+ }
386
491
  export {
387
492
  CacheError,
493
+ DeclarationInvalid,
388
494
  ElicitationFailed,
495
+ FetchOptionUnsupported,
496
+ NetworkRefused,
389
497
  NonRetryableError,
390
498
  NotImplemented,
391
499
  OAuth2AccessToken2 as OAuth2AccessToken,
@@ -394,18 +502,21 @@ export {
394
502
  ResponseStatusError,
395
503
  ValidationError,
396
504
  WorkflowFailure,
397
- accountOperations,
505
+ accountRouter,
506
+ appCron,
507
+ appInterval,
398
508
  array,
509
+ base64,
510
+ basic,
511
+ bearer,
399
512
  boolean,
400
- cron,
401
513
  decodeJson2 as decodeJson,
402
514
  defineApp,
403
- defineDatabase,
404
515
  defineProvider,
516
+ dynamicRouter,
405
517
  dynamicSkills,
406
- dynamicTools,
407
- id,
408
- interval,
518
+ event,
519
+ header,
409
520
  json,
410
521
  jsonSchema,
411
522
  literal,
@@ -413,12 +524,19 @@ export {
413
524
  number,
414
525
  oauth22 as oauth2,
415
526
  object,
416
- query,
527
+ plain,
528
+ query3 as query,
529
+ raw,
417
530
  record,
531
+ renameTools,
532
+ router,
418
533
  secrets2 as secrets,
419
534
  string,
420
- table,
421
- userId,
535
+ t,
536
+ toolAnnotations,
537
+ userCron,
538
+ userInterval,
422
539
  withApproval,
540
+ withApprovals,
423
541
  workflow
424
542
  };