apps 0.0.1-beta.23 → 0.0.1-beta.25

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 (71) hide show
  1. package/framework-reference.json +1 -1
  2. package/js/{chunk-IJX4CYZO.js → chunk-2TP7C25K.js} +3 -3
  3. package/js/{chunk-KUMBKVJD.js → chunk-3YN4UDPB.js} +2 -2
  4. package/js/{chunk-M3B3DE4K.js → chunk-AAAMPT6F.js} +2 -2
  5. package/js/chunk-DAIW2WM3.js +118 -0
  6. package/js/{chunk-CDL5PM2Q.js → chunk-DM5U7G7V.js} +124 -124
  7. package/js/{chunk-ODEIDRGW.js → chunk-DUEZ2XCO.js} +3 -3
  8. package/js/{chunk-K2QATKIF.js → chunk-GG4IFBN3.js} +77 -22
  9. package/js/{chunk-N7YDVXYJ.js → chunk-GH6PY5BQ.js} +1 -1
  10. package/js/{chunk-PZB6T6KU.js → chunk-HQKIPKM5.js} +1 -1
  11. package/js/{chunk-66JAEDTE.js → chunk-IE6W5RNN.js} +2 -2
  12. package/js/{chunk-WFEUCUFF.js → chunk-J3RUZMLO.js} +88 -26
  13. package/js/{chunk-JWNSH5CA.js → chunk-K3MQX2KO.js} +2 -2
  14. package/js/{chunk-27F7W2LG.js → chunk-KKGRSXUK.js} +1 -1
  15. package/js/{chunk-57RKNWL2.js → chunk-KNJAOYV4.js} +2 -2
  16. package/js/{chunk-ZQINWV4W.js → chunk-LPN4ONWW.js} +2 -2
  17. package/js/{chunk-A5BSZKFF.js → chunk-NXO2GN2T.js} +8 -8
  18. package/js/{chunk-UK573G7W.js → chunk-OBXHLFGQ.js} +1 -1
  19. package/js/{chunk-IPI4MFSN.js → chunk-PC5RHPUP.js} +2 -2
  20. package/js/{chunk-VFZKSM3T.js → chunk-SUY33XAY.js} +1 -1
  21. package/js/{chunk-R3EV5FTO.js → chunk-T7WRQJUF.js} +55 -3
  22. package/js/{chunk-JU7VHODU.js → chunk-TACLXEAE.js} +1 -1
  23. package/js/{chunk-2KZ7GG43.js → chunk-VGEPL4BV.js} +146 -53
  24. package/js/{chunk-B3T7CZOH.js → chunk-VSLWGXPW.js} +29 -7
  25. package/js/{chunk-3HH4OZR3.js → chunk-VWU6I23D.js} +23 -25
  26. package/js/{chunk-S47NFEWF.js → chunk-WPKXOTKM.js} +3 -3
  27. package/js/{chunk-PJJ24GU7.js → chunk-XBG3M64K.js} +1 -1
  28. package/js/{chunk-AK54RD3A.js → chunk-XIRAIB3P.js} +4 -4
  29. package/js/{chunk-NKLWZJLE.js → chunk-ZVMZWXVF.js} +2 -2
  30. package/js/client.js +115 -65
  31. package/js/contracts.js +36 -14
  32. package/js/effect.js +19 -19
  33. package/js/graphql.js +21 -21
  34. package/js/host.js +19 -19
  35. package/js/index.js +12 -12
  36. package/js/mcp/effect.js +21 -21
  37. package/js/mcp/stdio.js +30 -25
  38. package/js/mcp.js +23 -23
  39. package/js/openapi.js +15 -15
  40. package/js/react.js +3 -3
  41. package/js/skills/effect.js +3 -3
  42. package/js/skills.js +11 -11
  43. package/js/storage/facet.js +4 -4
  44. package/js/ui/auth/contracts.js +2 -2
  45. package/js/ui/auth.js +5 -5
  46. package/js/ui/contracts.js +4 -4
  47. package/js/ui/serving.js +8 -8
  48. package/package.json +1 -1
  49. package/runtime.json +1 -1
  50. package/types/apps/src/contracts/api-response-error.d.ts +4 -0
  51. package/types/apps/src/contracts/failure.d.ts +30 -1
  52. package/types/apps/src/contracts/host.d.ts +5 -4
  53. package/types/apps/src/contracts/mcp.d.ts +8 -1
  54. package/types/apps/src/contracts/protocol-version.d.ts +2 -2
  55. package/types/apps/src/contracts/protocols/1.d.ts +16 -2
  56. package/types/apps/src/contracts/protocols/2.d.ts +1 -1
  57. package/types/apps/src/contracts/protocols/3.d.ts +1 -3
  58. package/types/apps/src/contracts/protocols/4.d.ts +1 -2
  59. package/types/apps/src/contracts/protocols/5.d.ts +3 -3
  60. package/types/apps/src/contracts/protocols/6.d.ts +3 -3
  61. package/types/apps/src/contracts/protocols/7.d.ts +3 -3
  62. package/types/apps/src/contracts/protocols/8.d.ts +1119 -0
  63. package/types/apps/src/contracts/provider-error.d.ts +9 -0
  64. package/types/apps/src/implementation/failure-detail.d.ts +22 -3
  65. package/types/apps/src/implementation/mcp-client.d.ts +6 -0
  66. package/types/apps/src/implementation/provider-error.d.ts +28 -1
  67. package/types/apps/src/implementation/router-catalog.d.ts +2 -3
  68. package/types/apps/src/implementation/ui-client.d.ts +2 -2
  69. package/types/apps/src/implementation/upstream-error.d.ts +7 -0
  70. package/types/telemetry/src/config.d.ts +2 -2
  71. package/js/chunk-MKWZPDR6.js +0 -63
@@ -3,12 +3,21 @@ declare const ProviderError_base: Schema.Class<ProviderError, Schema.TaggedStruc
3
3
  readonly reason: Schema.Literals<readonly ["unauthorized", "forbidden", "rate_limited", "unavailable", "rejected"]>;
4
4
  readonly status: Schema.optional<Schema.Int>;
5
5
  readonly accountId: Schema.optional<Schema.brand<Schema.String, "acc">>;
6
+ readonly phase: Schema.optional<Schema.Literals<readonly ["connect", "discover", "call"]>>;
7
+ readonly upstream: Schema.optional<Schema.Struct<{
8
+ readonly code: Schema.Union<readonly [Schema.Int, Schema.String]>;
9
+ readonly message: Schema.optionalKey<Schema.String>;
10
+ }>>;
6
11
  }>, import("effect/Cause").YieldableError>;
7
12
  /**
8
13
  * A recognized service failure. App authors can throw this ordinary Error from
9
14
  * async code. Supply only a known reason and the account used for that request.
10
15
  * Never include response bodies, messages, URLs or credentials. A bare 403 is
11
16
  * `rejected`; `forbidden` requires explicit evidence of insufficient permission.
17
+ *
18
+ * The framework adds the phase the failure happened in, and `upstream`: the error code and
19
+ * description the service stated in its documented error format, such as a Bearer challenge's
20
+ * `error` and `error_description`. Account secrets in that text are replaced.
12
21
  */
13
22
  export declare class ProviderError extends ProviderError_base {
14
23
  }
@@ -1,11 +1,15 @@
1
- import { Redacted } from "effect";
1
+ import { Option, Redacted } from "effect";
2
2
  import type { ResolvedAccounts } from "../contracts/host.js";
3
+ import { McpError } from "../contracts/mcp.js";
4
+ import type { ProviderError } from "../contracts/provider-error.js";
5
+ import { type FailureFields, type FailurePhase, type UpstreamError } from "../contracts/failure.js";
3
6
  /** Fields of `FailureDetail` as constructor input. */
4
7
  export interface FailureDetail {
5
8
  readonly source?: "app" | "storage" | "service";
6
9
  readonly errorName?: string;
7
10
  readonly code?: string;
8
11
  readonly message?: string;
12
+ readonly fields?: FailureFields;
9
13
  }
10
14
  /**
11
15
  * Every credential field value of a slot-to-account record, longest first. Accepts both resolved
@@ -16,11 +20,26 @@ export declare const accountFieldSecrets: (accounts: unknown) => string[];
16
20
  export declare const accountSecrets: (accounts: Redacted.Redacted<ResolvedAccounts>) => string[];
17
21
  /** Replace account secrets and bound the message for the runtime boundary. */
18
22
  export declare const boundFailureMessage: (message: string, secrets: readonly string[]) => string;
23
+ /**
24
+ * Replace account secrets in the error a service stated, as it leaves the bundle. A message
25
+ * shortened where it was read can end partway through a secret; that part is replaced too.
26
+ */
27
+ export declare const redactUpstream: (upstream: UpstreamError | undefined, secrets: readonly string[]) => UpstreamError | undefined;
28
+ /**
29
+ * A provider failure as it leaves the bundle: in the phase it happened, unless its raiser named a
30
+ * more precise one, with account secrets replaced in the error the service stated.
31
+ */
32
+ export declare const leavingProviderError: (error: ProviderError, secrets: readonly string[], phase?: FailurePhase) => ProviderError;
33
+ /**
34
+ * Rebuild an MCP failure's allowlisted fields, with account secrets replaced in the server's
35
+ * error. Absent fields have no key, as catalogs cross the boundary as JSON values.
36
+ */
37
+ export declare const parseMcpError: (error: unknown, secrets: readonly string[]) => Option.Option<McpError>;
19
38
  /** `Name: message` for any thrown value, before redaction. */
20
39
  export declare const describeFailure: (error: unknown) => string;
21
40
  /**
22
41
  * Describe what an operation raised for the app's own caller. App data failures keep their
23
- * reason as a code, as do app cache failures; any other thrown value is the app's own error.
24
- * Account secrets are replaced.
42
+ * reason as a code, as do app cache failures; any other thrown value is the app's own error, with
43
+ * its own code and scalar fields. Account secrets are replaced.
25
44
  */
26
45
  export declare const failureDetail: (error: unknown, secrets: readonly string[]) => FailureDetail;
@@ -4,7 +4,13 @@ import type { Client } from "@modelcontextprotocol/sdk/client/index.js";
4
4
  import type { jsonSchemaValidator } from "@modelcontextprotocol/sdk/validation/types.js";
5
5
  import { Effect, Schema } from "effect";
6
6
  import { McpError, type McpToolContext } from "../contracts/mcp.js";
7
+ import type { UpstreamError } from "../contracts/failure.js";
7
8
  import type { JsonObject } from "../effect.js";
9
+ /**
10
+ * The JSON-RPC error a server answered a request with, if `error` is one. The SDK formats its
11
+ * message as `MCP error <code>: <message>`; the server's own message follows that prefix.
12
+ */
13
+ export declare const answeredError: (error: unknown) => UpstreamError | undefined;
8
14
  /** Use the framework-owned interpreter at the MCP SDK's synchronous validation boundary. */
9
15
  export declare const mcpJsonSchemaValidator: jsonSchemaValidator;
10
16
  /** An operation owns its connection; it must close even when interrupted. */
@@ -1,10 +1,37 @@
1
1
  import { Option } from "effect";
2
+ import type { FailurePhase, UpstreamError } from "../contracts/failure.js";
2
3
  import { ProviderError } from "../contracts/provider-error.js";
4
+ import { AccountId } from "../contracts/schema.js";
5
+ /** A provider failure's fields, each optional one possibly absent. */
6
+ interface ProviderErrorFields {
7
+ readonly reason: ProviderError["reason"];
8
+ readonly status?: number | undefined;
9
+ readonly accountId?: AccountId | undefined;
10
+ readonly phase?: FailurePhase | undefined;
11
+ readonly upstream?: UpstreamError | undefined;
12
+ }
13
+ /**
14
+ * Construct a provider failure without keys for absent fields. Failures inside a catalog cross the
15
+ * boundary as JSON values, which have no `undefined`.
16
+ */
17
+ export declare const providerError: ({ reason, status, accountId, phase, upstream, }: ProviderErrorFields) => ProviderError;
3
18
  /** Parse and rebuild the allowlisted fields, including when the input is already an Error instance. */
4
19
  export declare function parseProviderError(error: unknown): Option.Option<ProviderError>;
5
- /** Classify only explicit HTTP evidence. Raw provider content never enters the error. */
20
+ /**
21
+ * The same failure with detail its raiser could not know: the phase it happened in, and the
22
+ * error the service stated. Detail the failure already carries is kept.
23
+ */
24
+ export declare function providerErrorDetail(error: ProviderError, detail: {
25
+ readonly phase?: FailurePhase;
26
+ readonly upstream?: UpstreamError | undefined;
27
+ }): ProviderError;
28
+ /**
29
+ * Classify only explicit HTTP evidence. Raw provider content never enters the error; a Bearer
30
+ * challenge's documented error code and description do.
31
+ */
6
32
  export declare function httpProviderError(status: number, headers?: Readonly<Record<string, string>>): ProviderError | undefined;
7
33
  /** Attach the account used by the enclosing operation, without preserving arbitrary thrown fields. */
8
34
  export declare function accountProviderError<E>(error: E, accountId: string): E | ProviderError;
9
35
  /** GraphQL has no standard auth code; recognize these documented codes without guessing from prose. */
10
36
  export declare function graphqlProviderError(errors: readonly unknown[], status: number): ProviderError | undefined;
37
+ export {};
@@ -4,7 +4,6 @@
4
4
  */
5
5
  import { Effect, Schema } from "effect";
6
6
  import { HostDeclarationInvalid, HostEvaluationFailed, type HostRouterError } from "../contracts/host.js";
7
- import { McpError } from "../contracts/mcp.js";
8
7
  import type { AppOperation } from "../contracts/operations.js";
9
8
  import type { AppRouter, DynamicRouter, RouterMeta } from "../contracts/router.js";
10
9
  import { SkillLoadFailed } from "../contracts/skills.js";
@@ -189,7 +188,7 @@ export declare const readCatalog: (root: AppRouter | DynamicRouter | undefined,
189
188
  })[];
190
189
  routers: {
191
190
  readonly path: string;
192
- readonly error?: import("../index.js").ProviderError | SkillLoadFailed | McpError | HostDeclarationInvalid | HostEvaluationFailed;
191
+ readonly error?: import("../index.js").ProviderError | SkillLoadFailed | HostDeclarationInvalid | HostEvaluationFailed | import("../mcp.js").McpError;
193
192
  readonly description?: string;
194
193
  readonly title?: string;
195
194
  readonly tags?: {
@@ -203,7 +202,7 @@ export declare const readCatalog: (root: AppRouter | DynamicRouter | undefined,
203
202
  }[];
204
203
  readonly skill?: string;
205
204
  }[];
206
- }, import("../index.js").ProviderError | SkillLoadFailed | McpError | HostDeclarationInvalid | HostEvaluationFailed, never>;
205
+ }, import("../index.js").ProviderError | SkillLoadFailed | HostDeclarationInvalid | HostEvaluationFailed | import("../mcp.js").McpError, never>;
207
206
  /**
208
207
  * One skill for each router with instructions. Skills and tools fail independently: a dynamic
209
208
  * router whose metadata cannot be read, including the root, contributes no skill and does not
@@ -1,4 +1,4 @@
1
- import { Atom } from "effect/unstable/reactivity";
1
+ import { AsyncResult, Atom } from "effect/unstable/reactivity";
2
2
  import { type OperationReference } from "../contracts/live.js";
3
3
  import { type Schema } from "./schema.js";
4
4
  /** A scoped page client. Host-injected context carries only the deployment, never credentials. */
@@ -12,5 +12,5 @@ export declare const createAppClient: () => {
12
12
  /** Create a callable mutation with optional withOptimisticUpdate projections over mounted queries. */
13
13
  mutation: <Input, Output>(reference: OperationReference<Input, Output, "mutation">, output: Schema<NoInfer<Output>, boolean>) => import("../client.js").AppMutation<Input, Output>;
14
14
  /** Share a live query across mounts and reconcile optimistic changes against fresh server reads. */
15
- queryAtom: <Input, Output>(reference: OperationReference<Input, Output, "query">, input: NoInfer<Input>, output: Schema<NoInfer<Output>, boolean>) => Atom.Atom<import("effect/unstable/reactivity/AsyncResult").AsyncResult<Output, unknown>>;
15
+ queryAtom: <Input, Output>(reference: OperationReference<Input, Output, "query">, input: NoInfer<Input>, output: Schema<NoInfer<Output>, boolean>) => Atom.Atom<AsyncResult.AsyncResult<Output, unknown>>;
16
16
  };
@@ -0,0 +1,7 @@
1
+ import { UpstreamError } from "../contracts/failure.js";
2
+ /** Whether `bounded` shortened this message, so it may end partway through a secret. */
3
+ export declare const isShortenedUpstream: (message: string) => boolean;
4
+ /** The error a JSON error body states, if it uses JSON-RPC's or OAuth's error format. */
5
+ export declare const bodyUpstreamError: (json: unknown) => UpstreamError | undefined;
6
+ /** The `error` and `error_description` of a Bearer challenge (RFC 6750, section 3). */
7
+ export declare const challengeUpstreamError: (header: string | undefined) => UpstreamError | undefined;
@@ -33,8 +33,8 @@ export declare const TelemetryConfig: Schema.Struct<{
33
33
  export type TelemetryConfig = typeof TelemetryConfig.Type;
34
34
  /** Host-only destinations; never copied into an app's invocation telemetry capability. */
35
35
  export declare const CurrentTelemetryConfig: Context.Reference<{
36
- readonly version: string;
37
36
  readonly service: string;
37
+ readonly version: string;
38
38
  readonly environment: string;
39
39
  readonly clock?: "system" | "cloudflare-io" | undefined;
40
40
  readonly traces?: {
@@ -59,8 +59,8 @@ export declare const CurrentTelemetryConfig: Context.Reference<{
59
59
  } | undefined>;
60
60
  /** Read OTLP endpoints uniformly for all signals; development chooses which signals to configure. */
61
61
  export declare const telemetryConfig: (service: string) => Effect.Effect<{
62
- readonly version: string;
63
62
  readonly service: string;
63
+ readonly version: string;
64
64
  readonly environment: string;
65
65
  readonly clock?: "system" | "cloudflare-io" | undefined;
66
66
  readonly traces?: {
@@ -1,63 +0,0 @@
1
- import {
2
- ProviderError
3
- } from "./chunk-R3EV5FTO.js";
4
- import {
5
- AccountId
6
- } from "./chunk-27F7W2LG.js";
7
- import {
8
- Option_exports,
9
- Schema_exports
10
- } from "./chunk-CDL5PM2Q.js";
11
-
12
- // src/implementation/provider-error.ts
13
- function parseProviderError(error) {
14
- return Schema_exports.decodeUnknownOption(ProviderError)(error).pipe(
15
- Option_exports.map(({ reason, status, accountId }) => new ProviderError({ reason, status, accountId }))
16
- );
17
- }
18
- function httpProviderError(status, headers = {}) {
19
- if (status >= 500 && status <= 599) return new ProviderError({ reason: "unavailable", status });
20
- if (status === 401) return new ProviderError({ reason: "unauthorized", status });
21
- if (status === 429) return new ProviderError({ reason: "rate_limited", status });
22
- if (status !== 403) return void 0;
23
- const retry = headers["retry-after"];
24
- if (headers["x-ratelimit-remaining"] === "0" || retry !== void 0 && (/^\d+$/.test(retry) || Number.isFinite(Date.parse(retry))))
25
- return new ProviderError({ reason: "rate_limited", status });
26
- if (/\bBearer\b.*\berror="insufficient_scope"/i.test(headers["www-authenticate"] ?? ""))
27
- return new ProviderError({ reason: "forbidden", status });
28
- return new ProviderError({ reason: "rejected", status });
29
- }
30
- function accountProviderError(error, accountId) {
31
- const parsed = parseProviderError(error);
32
- const account = Schema_exports.decodeUnknownOption(AccountId)(accountId);
33
- if (Option_exports.isNone(parsed) || Option_exports.isNone(account)) return error;
34
- return new ProviderError({
35
- reason: parsed.value.reason,
36
- status: parsed.value.status,
37
- accountId: account.value
38
- });
39
- }
40
- function graphqlProviderError(errors, status) {
41
- const codes = errors.flatMap((error) => {
42
- const parsed = Schema_exports.decodeUnknownOption(
43
- Schema_exports.Struct({
44
- type: Schema_exports.optional(Schema_exports.String),
45
- extensions: Schema_exports.optional(Schema_exports.Struct({ code: Schema_exports.optional(Schema_exports.String) }))
46
- })
47
- )(error);
48
- return Option_exports.isSome(parsed) ? [parsed.value.type, parsed.value.extensions?.code] : [];
49
- });
50
- if (codes.includes("RATE_LIMITED") || codes.includes("TOO_MANY_REQUESTS"))
51
- return new ProviderError({ reason: "rate_limited", status });
52
- if (codes.includes("UNAUTHENTICATED"))
53
- return new ProviderError({ reason: "unauthorized", status });
54
- if (codes.includes("FORBIDDEN")) return new ProviderError({ reason: "forbidden", status });
55
- return void 0;
56
- }
57
-
58
- export {
59
- parseProviderError,
60
- httpProviderError,
61
- accountProviderError,
62
- graphqlProviderError
63
- };