@ethisyscore/extension-runtime 1.135.0 → 1.137.0

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 (34) hide show
  1. package/README.md +2 -2
  2. package/dist/MockPluginStorage-BM3bq99B.d.cts +35 -0
  3. package/dist/MockPluginStorage-BndTX2RR.d.ts +35 -0
  4. package/dist/{bridge-client-RJOl8WlU.d.ts → bridge-client-CkxYcZcm.d.ts} +1 -1
  5. package/dist/{bridge-client-D9EYFq1l.d.cts → bridge-client-DkogtCvn.d.cts} +1 -1
  6. package/dist/{bridge-envelopes-M5a42rAy.d.cts → bridge-envelopes-BcKu-nQm.d.cts} +72 -1
  7. package/dist/{bridge-envelopes-M5a42rAy.d.ts → bridge-envelopes-BcKu-nQm.d.ts} +72 -1
  8. package/dist/host/index.cjs +57 -2
  9. package/dist/host/index.cjs.map +1 -1
  10. package/dist/host/index.d.cts +3 -3
  11. package/dist/host/index.d.ts +3 -3
  12. package/dist/host/index.js +57 -2
  13. package/dist/host/index.js.map +1 -1
  14. package/dist/mock-host/cli.cjs +273 -7
  15. package/dist/mock-host/cli.cjs.map +1 -1
  16. package/dist/mock-host/cli.d.cts +10 -3
  17. package/dist/mock-host/cli.d.ts +10 -3
  18. package/dist/mock-host/cli.js +272 -8
  19. package/dist/mock-host/cli.js.map +1 -1
  20. package/dist/mock-host/index.cjs +236 -1
  21. package/dist/mock-host/index.cjs.map +1 -1
  22. package/dist/mock-host/index.d.cts +14 -4
  23. package/dist/mock-host/index.d.ts +14 -4
  24. package/dist/mock-host/index.js +236 -2
  25. package/dist/mock-host/index.js.map +1 -1
  26. package/dist/plugin/index.cjs +378 -100
  27. package/dist/plugin/index.cjs.map +1 -1
  28. package/dist/plugin/index.d.cts +171 -6
  29. package/dist/plugin/index.d.ts +171 -6
  30. package/dist/plugin/index.js +366 -101
  31. package/dist/plugin/index.js.map +1 -1
  32. package/dist/{transport-UaoDRdm3.d.cts → transport-D1lE-5nt.d.cts} +30 -3
  33. package/dist/{transport-CFzJQiFG.d.ts → transport-INVtDo2s.d.ts} +30 -3
  34. package/package.json +1 -1
@@ -1,13 +1,178 @@
1
- import { M as McpTransport } from '../bridge-envelopes-M5a42rAy.cjs';
2
- export { U as UploadDocumentMeta, f as UploadDocumentResult } from '../bridge-envelopes-M5a42rAy.cjs';
1
+ import { M as McpTransport, h as UploadToStorageResult } from '../bridge-envelopes-BcKu-nQm.cjs';
2
+ export { U as UploadDocumentMeta, f as UploadDocumentResult, g as UploadToStorageMeta } from '../bridge-envelopes-BcKu-nQm.cjs';
3
+ import { b as McpToolError, a as McpErrorCode } from '../mcp-error-CCZQd8Xl.cjs';
4
+ export { M as MCP_ERROR_CODES, c as classifyHostError, d as classifyHostResponse, i as isMcpErrorCode, e as isMcpToolError, f as isRetryableMcpErrorCode, m as mcpErrorCodeFromHttpStatus } from '../mcp-error-CCZQd8Xl.cjs';
3
5
  import * as react from 'react';
4
6
  import { ReactNode } from 'react';
5
7
  import { SduiNode, RenderMode } from '@ethisyscore/protocol';
6
8
  export { PagedResponse, PaginatedEnvelope } from '@ethisyscore/protocol';
7
9
  import { RemoteConnection } from '@remote-dom/core';
8
- import { P as PortBridgeClient, T as ThemePayload, L as LocalePayload } from '../bridge-client-D9EYFq1l.cjs';
9
- export { A as A11yPayload, B as BridgePortShim, D as DensityPayload, N as NavPayload, S as SessionTokenPayload, c as createPortBridgeClient } from '../bridge-client-D9EYFq1l.cjs';
10
- export { M as MCP_ERROR_CODES, a as McpErrorCode, b as McpToolError, c as classifyHostError, d as classifyHostResponse, i as isMcpErrorCode, e as isMcpToolError, f as isRetryableMcpErrorCode, m as mcpErrorCodeFromHttpStatus } from '../mcp-error-CCZQd8Xl.cjs';
10
+ import { P as PortBridgeClient, T as ThemePayload, L as LocalePayload } from '../bridge-client-DkogtCvn.cjs';
11
+ export { A as A11yPayload, B as BridgePortShim, D as DensityPayload, N as NavPayload, S as SessionTokenPayload, c as createPortBridgeClient } from '../bridge-client-DkogtCvn.cjs';
12
+
13
+ /**
14
+ * Browser file → the calling app's OWN plugin storage.
15
+ *
16
+ * The plugin-facing half of the `uploadToStorage` request kind: client-side prefix validation that
17
+ * mirrors the kernel's `PluginStorageUploadPath.TryNormalizePrefix`, a typed error that keeps the
18
+ * server's status and message, and {@link uploadFileToPluginStorage}, the one function every
19
+ * plugin surface (and `@ethisyscore/plugin-ui`'s `useUploadToStorage`) calls.
20
+ *
21
+ * Browser uploads go through `uploadToStorage` into plugin storage; never base64 a file through a
22
+ * tool call.
23
+ *
24
+ * The client checks are there to fail fast, before a 30 MB file is read into memory. The server
25
+ * re-runs every one of them and is authoritative.
26
+ */
27
+
28
+ /** The kernel's hard cap on one upload, in bytes (`UploadExtensionDocumentStream.MaxUploadBytes`). */
29
+ declare const PLUGIN_STORAGE_UPLOAD_MAX_BYTES: number;
30
+ /**
31
+ * Maximum length of a normalised prefix: 128 (the path column HR and Legal record into) less the
32
+ * `/`, the 32-character GUID leaf and an 11-character extension. `governance/{guid}/{guid}` is
33
+ * exactly 84.
34
+ */
35
+ declare const PLUGIN_STORAGE_PREFIX_MAX_LENGTH = 84;
36
+ /** Maximum length of a path the server returns. */
37
+ declare const PLUGIN_STORAGE_PATH_MAX_LENGTH = 128;
38
+ /**
39
+ * Why a plugin-storage upload failed. Each value is something a caller can act on differently;
40
+ * `status` on the error carries the exact HTTP status when the host supplied one.
41
+ *
42
+ * - `invalid_prefix`: the prefix broke the rules (client-side check, or a server 400).
43
+ * - `too_large`: over the 30 MB cap (client-side check, or a server 413).
44
+ * - `quota_exceeded`: the app's storage quota would be exceeded (507).
45
+ * - `unauthorized`: no capability-token caller or no session (401).
46
+ * - `forbidden`: token and session disagree, or the app owns no storage namespace (403).
47
+ * - `unsupported_type`: the file's extension is not on the allow-list, or the declared type does
48
+ * not match it (client-side check, or a server 415).
49
+ * - `timeout`: the upload was too slow or missed the server's deadline (408). Retryable.
50
+ * - `busy`: the app's storage lock is held, or the server's upload slots are full (503). Retryable.
51
+ * - `storage_failed`: the store refused the write (500).
52
+ * - `unsupported`: the active transport has no `uploadToStorage`, i.e. the host predates it.
53
+ * - `aborted`: the caller's signal fired.
54
+ * - `unknown`: anything else.
55
+ */
56
+ type PluginStorageUploadErrorReason = "invalid_prefix" | "too_large" | "quota_exceeded" | "unauthorized" | "forbidden" | "unsupported_type" | "timeout" | "busy" | "storage_failed" | "unsupported" | "aborted" | "unknown";
57
+ /**
58
+ * A failed plugin-storage upload. `message` is the server's own `{ error }` text when the server
59
+ * answered, otherwise the client-side reason.
60
+ *
61
+ * Extends {@link McpToolError}, so `isMcpToolError` and `code` keep working for code that handles
62
+ * every MCP failure the same way. Prefer {@link isPluginStorageUploadError} over `instanceof`: the
63
+ * error can be built in one bundle and inspected in another.
64
+ */
65
+ declare class PluginStorageUploadError extends McpToolError {
66
+ /** What went wrong, in terms a caller branches on. */
67
+ readonly reason: PluginStorageUploadErrorReason;
68
+ /** HTTP status from the server, when the host surfaced one. */
69
+ readonly status?: number;
70
+ /** Structural marker for {@link isPluginStorageUploadError}. */
71
+ readonly isPluginStorageUploadError: true;
72
+ constructor(message: string, reason: PluginStorageUploadErrorReason, options?: {
73
+ status?: number;
74
+ code?: McpErrorCode;
75
+ });
76
+ }
77
+ /** True when `value` is a {@link PluginStorageUploadError}, including one from another bundle. */
78
+ declare function isPluginStorageUploadError(value: unknown): value is PluginStorageUploadError;
79
+ /** Maps a status from `extensions/storage/upload-stream` onto a {@link PluginStorageUploadErrorReason}. */
80
+ declare function pluginStorageUploadReasonFromStatus(status: number): PluginStorageUploadErrorReason;
81
+ /**
82
+ * Normalises any failure from a transport's `uploadToStorage` into a {@link PluginStorageUploadError},
83
+ * keeping the server's message.
84
+ *
85
+ * Precedence: an existing `PluginStorageUploadError` passes through; then a numeric `status` /
86
+ * `statusCode` (what a host HTTP client carries); then an `AbortError`; then the MCP error `code`
87
+ * from the bridge; then `unknown`. Never inferred from the message text.
88
+ */
89
+ declare function toPluginStorageUploadError(err: unknown): PluginStorageUploadError;
90
+ /** Outcome of {@link validatePluginStoragePrefix}. */
91
+ type PluginStoragePrefixValidation = {
92
+ readonly ok: true;
93
+ readonly prefix: string;
94
+ } | {
95
+ readonly ok: false;
96
+ readonly error: string;
97
+ };
98
+ /**
99
+ * Validates a storage prefix with the kernel's rules (`PluginStorageUploadPath.TryNormalizePrefix`
100
+ * in CoreConnect-Api, Application.Extensions/Storage). A malformed prefix is REFUSED, never
101
+ * repaired, and an accepted one is returned exactly as given, so a caller that checks the
102
+ * returned path with `path.startsWith(prefix + "/")` always matches. In the server's order:
103
+ *
104
+ * - required (not empty or whitespace);
105
+ * - at most {@link PLUGIN_STORAGE_PREFIX_MAX_LENGTH} characters, measured on the raw value;
106
+ * - only `[A-Za-z0-9_-]` and `/`, so `%` (any encoding), `.`/`..`, `\`, whitespace and every
107
+ * other character are refused;
108
+ * - every `/`-separated segment non-empty, which also refuses a leading or trailing `/` and `//`.
109
+ *
110
+ * The server's last check (its storage normaliser must be the identity on the prefix) cannot fail
111
+ * for a value that passed the rules above, so it has no client counterpart.
112
+ */
113
+ declare function validatePluginStoragePrefix(raw: string | null | undefined): PluginStoragePrefixValidation;
114
+ /**
115
+ * {@link validatePluginStoragePrefix}, throwing a `PluginStorageUploadError` with reason
116
+ * `invalid_prefix` instead of returning a result. Returns the prefix unchanged.
117
+ */
118
+ declare function assertValidPluginStoragePrefix(raw: string): string;
119
+ /**
120
+ * The file types a browser may upload into plugin storage, keyed by lower-case extension: the
121
+ * canonical type the server stores first, then the aliases browsers commonly declare for it.
122
+ *
123
+ * SOURCE OF TRUTH: `PluginStorageUploadContentTypes` in CoreConnect-Api
124
+ * (src/application/CoreConnect.Application.Extensions/Storage/PluginStorageUploadContentTypes.cs).
125
+ * This copy only lets the client fail fast with `unsupported_type`; the server decides. Keep it in
126
+ * step with the server. Passive formats only: never HTML, SVG, XML or JavaScript.
127
+ */
128
+ declare const PLUGIN_STORAGE_UPLOAD_CONTENT_TYPES: Readonly<Record<string, readonly [canonical: string, ...aliases: string[]]>>;
129
+ /**
130
+ * The kernel's `PluginStorageUploadPath.SafeExtension`: the lower-cased extension with its dot,
131
+ * kept only when it is 1 to 10 ASCII letters or digits; otherwise empty.
132
+ */
133
+ declare function pluginStorageSafeExtension(fileName: string | null | undefined): string;
134
+ /** Outcome of {@link resolvePluginStorageContentType}. */
135
+ type PluginStorageContentTypeResolution = {
136
+ readonly ok: true;
137
+ readonly contentType: string;
138
+ } | {
139
+ readonly ok: false;
140
+ readonly error: string;
141
+ };
142
+ /**
143
+ * Mirrors `PluginStorageUploadContentTypes.TryResolve`: the extension decides. A file name with no
144
+ * allow-listed extension is refused. A declared type is accepted when it is that extension's
145
+ * canonical type or a listed alias (case-insensitive, parameters ignored); none, or
146
+ * `application/octet-stream`, means "use the extension's type". Resolves to the CANONICAL type the
147
+ * server will store.
148
+ */
149
+ declare function resolvePluginStorageContentType(fileName: string | null | undefined, declaredContentType?: string | null): PluginStorageContentTypeResolution;
150
+ /** Options for {@link uploadFileToPluginStorage}. */
151
+ interface UploadToStorageOptions {
152
+ /** Folder inside the app's own storage namespace, e.g. `cvs` or `governance/{docId}/{versionId}`. */
153
+ pathPrefix: string;
154
+ /** File name. Defaults to the `File`'s name, else `upload.bin`. Required in practice for an `ArrayBuffer`. */
155
+ fileName?: string;
156
+ /** MIME type. Defaults to the `Blob`'s type, else `application/octet-stream` (the server then infers from the extension). */
157
+ contentType?: string;
158
+ /** Client-side size ceiling, never above the server's. Defaults to {@link PLUGIN_STORAGE_UPLOAD_MAX_BYTES}. */
159
+ maxSizeBytes?: number;
160
+ /** Cancels the upload. */
161
+ signal?: AbortSignal;
162
+ }
163
+ /**
164
+ * Upload a browser file into the calling app's own plugin storage and resolve the server-chosen
165
+ * `path` that the app's backend reads with `IPluginStorage`.
166
+ *
167
+ * Validates the prefix, the size and the file type (against the server's allow-list) before
168
+ * reading the file, then hands the bytes to the
169
+ * transport's `uploadToStorage`. Every failure (client-side or server) rejects with a
170
+ * {@link PluginStorageUploadError} whose `reason` is safe to branch on and whose `message` is the
171
+ * server's when the server answered.
172
+ *
173
+ * An `ArrayBuffer` argument is transferred to the host and detached; pass a copy to keep it.
174
+ */
175
+ declare function uploadFileToPluginStorage(transport: McpTransport, file: File | Blob | ArrayBuffer, options: UploadToStorageOptions): Promise<UploadToStorageResult>;
11
176
 
12
177
  /**
13
178
  * A single client-push event delivered from the host to a plugin surface. The host
@@ -797,4 +962,4 @@ interface UseAuthResult {
797
962
  */
798
963
  declare function useAuth(transport: McpTransport): UseAuthResult;
799
964
 
800
- export { BridgeClientContext, type ClientPushChannel, ClientPushContext, type ClientPushEvent, type ClientPushSubscribeOptions, type CreatePortMcpTransportOptions, type CreateRemoteRootOptions, type DeclarativePluginConfig, type EthisysPluginConfig, ExtensionRuntimeProvider, type ExtensionRuntimeProviderProps, type HostIdentity, HostIdentityContext, type HostIdentityUser, type HostPermission, type ItemsResponse, LocalePayload, McpTransport, PluginRealtimeContext, type PluginRealtimeSource, PortBridgeClient, type PortShim, type RemoteRoot, ThemePayload, type UseAuthResult, type UseClientPushSubscriptionOptions, type UseFrontendSessionTokenResult, type UseMcpQueryOptions, type UseMcpQueryResult, type UseMcpResourceOptions, type UseMcpResourceResult, type UseMcpToolOptions, type UseMcpToolResult, type UseModuleQueryOptions, type UseModuleQueryResult, type UseModuleToolOptions, type UseModuleToolResult, createPortMcpTransport, createRemoteRoot, decodeJwtPayload, defineDeclarativePlugin, defineEthisysPlugin, unwrapItems, useAuth, useBridgeClient, useBridgeLocale, useBridgeTheme, useClientPushSubscription, useExtensionRuntimeTransport, useFrontendSessionToken, useHostIdentity, useMcpQuery, useMcpResource, useMcpTool, useModuleQuery, useModuleTool, useOptionalExtensionRuntimeTransport, usePluginRealtimeSource };
965
+ export { BridgeClientContext, type ClientPushChannel, ClientPushContext, type ClientPushEvent, type ClientPushSubscribeOptions, type CreatePortMcpTransportOptions, type CreateRemoteRootOptions, type DeclarativePluginConfig, type EthisysPluginConfig, ExtensionRuntimeProvider, type ExtensionRuntimeProviderProps, type HostIdentity, HostIdentityContext, type HostIdentityUser, type HostPermission, type ItemsResponse, LocalePayload, McpErrorCode, McpToolError, McpTransport, PLUGIN_STORAGE_PATH_MAX_LENGTH, PLUGIN_STORAGE_PREFIX_MAX_LENGTH, PLUGIN_STORAGE_UPLOAD_CONTENT_TYPES, PLUGIN_STORAGE_UPLOAD_MAX_BYTES, PluginRealtimeContext, type PluginRealtimeSource, type PluginStorageContentTypeResolution, type PluginStoragePrefixValidation, PluginStorageUploadError, type PluginStorageUploadErrorReason, PortBridgeClient, type PortShim, type RemoteRoot, ThemePayload, type UploadToStorageOptions, UploadToStorageResult, type UseAuthResult, type UseClientPushSubscriptionOptions, type UseFrontendSessionTokenResult, type UseMcpQueryOptions, type UseMcpQueryResult, type UseMcpResourceOptions, type UseMcpResourceResult, type UseMcpToolOptions, type UseMcpToolResult, type UseModuleQueryOptions, type UseModuleQueryResult, type UseModuleToolOptions, type UseModuleToolResult, assertValidPluginStoragePrefix, createPortMcpTransport, createRemoteRoot, decodeJwtPayload, defineDeclarativePlugin, defineEthisysPlugin, isPluginStorageUploadError, pluginStorageSafeExtension, pluginStorageUploadReasonFromStatus, resolvePluginStorageContentType, toPluginStorageUploadError, unwrapItems, uploadFileToPluginStorage, useAuth, useBridgeClient, useBridgeLocale, useBridgeTheme, useClientPushSubscription, useExtensionRuntimeTransport, useFrontendSessionToken, useHostIdentity, useMcpQuery, useMcpResource, useMcpTool, useModuleQuery, useModuleTool, useOptionalExtensionRuntimeTransport, usePluginRealtimeSource, validatePluginStoragePrefix };
@@ -1,13 +1,178 @@
1
- import { M as McpTransport } from '../bridge-envelopes-M5a42rAy.js';
2
- export { U as UploadDocumentMeta, f as UploadDocumentResult } from '../bridge-envelopes-M5a42rAy.js';
1
+ import { M as McpTransport, h as UploadToStorageResult } from '../bridge-envelopes-BcKu-nQm.js';
2
+ export { U as UploadDocumentMeta, f as UploadDocumentResult, g as UploadToStorageMeta } from '../bridge-envelopes-BcKu-nQm.js';
3
+ import { b as McpToolError, a as McpErrorCode } from '../mcp-error-CCZQd8Xl.js';
4
+ export { M as MCP_ERROR_CODES, c as classifyHostError, d as classifyHostResponse, i as isMcpErrorCode, e as isMcpToolError, f as isRetryableMcpErrorCode, m as mcpErrorCodeFromHttpStatus } from '../mcp-error-CCZQd8Xl.js';
3
5
  import * as react from 'react';
4
6
  import { ReactNode } from 'react';
5
7
  import { SduiNode, RenderMode } from '@ethisyscore/protocol';
6
8
  export { PagedResponse, PaginatedEnvelope } from '@ethisyscore/protocol';
7
9
  import { RemoteConnection } from '@remote-dom/core';
8
- import { P as PortBridgeClient, T as ThemePayload, L as LocalePayload } from '../bridge-client-RJOl8WlU.js';
9
- export { A as A11yPayload, B as BridgePortShim, D as DensityPayload, N as NavPayload, S as SessionTokenPayload, c as createPortBridgeClient } from '../bridge-client-RJOl8WlU.js';
10
- export { M as MCP_ERROR_CODES, a as McpErrorCode, b as McpToolError, c as classifyHostError, d as classifyHostResponse, i as isMcpErrorCode, e as isMcpToolError, f as isRetryableMcpErrorCode, m as mcpErrorCodeFromHttpStatus } from '../mcp-error-CCZQd8Xl.js';
10
+ import { P as PortBridgeClient, T as ThemePayload, L as LocalePayload } from '../bridge-client-CkxYcZcm.js';
11
+ export { A as A11yPayload, B as BridgePortShim, D as DensityPayload, N as NavPayload, S as SessionTokenPayload, c as createPortBridgeClient } from '../bridge-client-CkxYcZcm.js';
12
+
13
+ /**
14
+ * Browser file → the calling app's OWN plugin storage.
15
+ *
16
+ * The plugin-facing half of the `uploadToStorage` request kind: client-side prefix validation that
17
+ * mirrors the kernel's `PluginStorageUploadPath.TryNormalizePrefix`, a typed error that keeps the
18
+ * server's status and message, and {@link uploadFileToPluginStorage}, the one function every
19
+ * plugin surface (and `@ethisyscore/plugin-ui`'s `useUploadToStorage`) calls.
20
+ *
21
+ * Browser uploads go through `uploadToStorage` into plugin storage; never base64 a file through a
22
+ * tool call.
23
+ *
24
+ * The client checks are there to fail fast, before a 30 MB file is read into memory. The server
25
+ * re-runs every one of them and is authoritative.
26
+ */
27
+
28
+ /** The kernel's hard cap on one upload, in bytes (`UploadExtensionDocumentStream.MaxUploadBytes`). */
29
+ declare const PLUGIN_STORAGE_UPLOAD_MAX_BYTES: number;
30
+ /**
31
+ * Maximum length of a normalised prefix: 128 (the path column HR and Legal record into) less the
32
+ * `/`, the 32-character GUID leaf and an 11-character extension. `governance/{guid}/{guid}` is
33
+ * exactly 84.
34
+ */
35
+ declare const PLUGIN_STORAGE_PREFIX_MAX_LENGTH = 84;
36
+ /** Maximum length of a path the server returns. */
37
+ declare const PLUGIN_STORAGE_PATH_MAX_LENGTH = 128;
38
+ /**
39
+ * Why a plugin-storage upload failed. Each value is something a caller can act on differently;
40
+ * `status` on the error carries the exact HTTP status when the host supplied one.
41
+ *
42
+ * - `invalid_prefix`: the prefix broke the rules (client-side check, or a server 400).
43
+ * - `too_large`: over the 30 MB cap (client-side check, or a server 413).
44
+ * - `quota_exceeded`: the app's storage quota would be exceeded (507).
45
+ * - `unauthorized`: no capability-token caller or no session (401).
46
+ * - `forbidden`: token and session disagree, or the app owns no storage namespace (403).
47
+ * - `unsupported_type`: the file's extension is not on the allow-list, or the declared type does
48
+ * not match it (client-side check, or a server 415).
49
+ * - `timeout`: the upload was too slow or missed the server's deadline (408). Retryable.
50
+ * - `busy`: the app's storage lock is held, or the server's upload slots are full (503). Retryable.
51
+ * - `storage_failed`: the store refused the write (500).
52
+ * - `unsupported`: the active transport has no `uploadToStorage`, i.e. the host predates it.
53
+ * - `aborted`: the caller's signal fired.
54
+ * - `unknown`: anything else.
55
+ */
56
+ type PluginStorageUploadErrorReason = "invalid_prefix" | "too_large" | "quota_exceeded" | "unauthorized" | "forbidden" | "unsupported_type" | "timeout" | "busy" | "storage_failed" | "unsupported" | "aborted" | "unknown";
57
+ /**
58
+ * A failed plugin-storage upload. `message` is the server's own `{ error }` text when the server
59
+ * answered, otherwise the client-side reason.
60
+ *
61
+ * Extends {@link McpToolError}, so `isMcpToolError` and `code` keep working for code that handles
62
+ * every MCP failure the same way. Prefer {@link isPluginStorageUploadError} over `instanceof`: the
63
+ * error can be built in one bundle and inspected in another.
64
+ */
65
+ declare class PluginStorageUploadError extends McpToolError {
66
+ /** What went wrong, in terms a caller branches on. */
67
+ readonly reason: PluginStorageUploadErrorReason;
68
+ /** HTTP status from the server, when the host surfaced one. */
69
+ readonly status?: number;
70
+ /** Structural marker for {@link isPluginStorageUploadError}. */
71
+ readonly isPluginStorageUploadError: true;
72
+ constructor(message: string, reason: PluginStorageUploadErrorReason, options?: {
73
+ status?: number;
74
+ code?: McpErrorCode;
75
+ });
76
+ }
77
+ /** True when `value` is a {@link PluginStorageUploadError}, including one from another bundle. */
78
+ declare function isPluginStorageUploadError(value: unknown): value is PluginStorageUploadError;
79
+ /** Maps a status from `extensions/storage/upload-stream` onto a {@link PluginStorageUploadErrorReason}. */
80
+ declare function pluginStorageUploadReasonFromStatus(status: number): PluginStorageUploadErrorReason;
81
+ /**
82
+ * Normalises any failure from a transport's `uploadToStorage` into a {@link PluginStorageUploadError},
83
+ * keeping the server's message.
84
+ *
85
+ * Precedence: an existing `PluginStorageUploadError` passes through; then a numeric `status` /
86
+ * `statusCode` (what a host HTTP client carries); then an `AbortError`; then the MCP error `code`
87
+ * from the bridge; then `unknown`. Never inferred from the message text.
88
+ */
89
+ declare function toPluginStorageUploadError(err: unknown): PluginStorageUploadError;
90
+ /** Outcome of {@link validatePluginStoragePrefix}. */
91
+ type PluginStoragePrefixValidation = {
92
+ readonly ok: true;
93
+ readonly prefix: string;
94
+ } | {
95
+ readonly ok: false;
96
+ readonly error: string;
97
+ };
98
+ /**
99
+ * Validates a storage prefix with the kernel's rules (`PluginStorageUploadPath.TryNormalizePrefix`
100
+ * in CoreConnect-Api, Application.Extensions/Storage). A malformed prefix is REFUSED, never
101
+ * repaired, and an accepted one is returned exactly as given, so a caller that checks the
102
+ * returned path with `path.startsWith(prefix + "/")` always matches. In the server's order:
103
+ *
104
+ * - required (not empty or whitespace);
105
+ * - at most {@link PLUGIN_STORAGE_PREFIX_MAX_LENGTH} characters, measured on the raw value;
106
+ * - only `[A-Za-z0-9_-]` and `/`, so `%` (any encoding), `.`/`..`, `\`, whitespace and every
107
+ * other character are refused;
108
+ * - every `/`-separated segment non-empty, which also refuses a leading or trailing `/` and `//`.
109
+ *
110
+ * The server's last check (its storage normaliser must be the identity on the prefix) cannot fail
111
+ * for a value that passed the rules above, so it has no client counterpart.
112
+ */
113
+ declare function validatePluginStoragePrefix(raw: string | null | undefined): PluginStoragePrefixValidation;
114
+ /**
115
+ * {@link validatePluginStoragePrefix}, throwing a `PluginStorageUploadError` with reason
116
+ * `invalid_prefix` instead of returning a result. Returns the prefix unchanged.
117
+ */
118
+ declare function assertValidPluginStoragePrefix(raw: string): string;
119
+ /**
120
+ * The file types a browser may upload into plugin storage, keyed by lower-case extension: the
121
+ * canonical type the server stores first, then the aliases browsers commonly declare for it.
122
+ *
123
+ * SOURCE OF TRUTH: `PluginStorageUploadContentTypes` in CoreConnect-Api
124
+ * (src/application/CoreConnect.Application.Extensions/Storage/PluginStorageUploadContentTypes.cs).
125
+ * This copy only lets the client fail fast with `unsupported_type`; the server decides. Keep it in
126
+ * step with the server. Passive formats only: never HTML, SVG, XML or JavaScript.
127
+ */
128
+ declare const PLUGIN_STORAGE_UPLOAD_CONTENT_TYPES: Readonly<Record<string, readonly [canonical: string, ...aliases: string[]]>>;
129
+ /**
130
+ * The kernel's `PluginStorageUploadPath.SafeExtension`: the lower-cased extension with its dot,
131
+ * kept only when it is 1 to 10 ASCII letters or digits; otherwise empty.
132
+ */
133
+ declare function pluginStorageSafeExtension(fileName: string | null | undefined): string;
134
+ /** Outcome of {@link resolvePluginStorageContentType}. */
135
+ type PluginStorageContentTypeResolution = {
136
+ readonly ok: true;
137
+ readonly contentType: string;
138
+ } | {
139
+ readonly ok: false;
140
+ readonly error: string;
141
+ };
142
+ /**
143
+ * Mirrors `PluginStorageUploadContentTypes.TryResolve`: the extension decides. A file name with no
144
+ * allow-listed extension is refused. A declared type is accepted when it is that extension's
145
+ * canonical type or a listed alias (case-insensitive, parameters ignored); none, or
146
+ * `application/octet-stream`, means "use the extension's type". Resolves to the CANONICAL type the
147
+ * server will store.
148
+ */
149
+ declare function resolvePluginStorageContentType(fileName: string | null | undefined, declaredContentType?: string | null): PluginStorageContentTypeResolution;
150
+ /** Options for {@link uploadFileToPluginStorage}. */
151
+ interface UploadToStorageOptions {
152
+ /** Folder inside the app's own storage namespace, e.g. `cvs` or `governance/{docId}/{versionId}`. */
153
+ pathPrefix: string;
154
+ /** File name. Defaults to the `File`'s name, else `upload.bin`. Required in practice for an `ArrayBuffer`. */
155
+ fileName?: string;
156
+ /** MIME type. Defaults to the `Blob`'s type, else `application/octet-stream` (the server then infers from the extension). */
157
+ contentType?: string;
158
+ /** Client-side size ceiling, never above the server's. Defaults to {@link PLUGIN_STORAGE_UPLOAD_MAX_BYTES}. */
159
+ maxSizeBytes?: number;
160
+ /** Cancels the upload. */
161
+ signal?: AbortSignal;
162
+ }
163
+ /**
164
+ * Upload a browser file into the calling app's own plugin storage and resolve the server-chosen
165
+ * `path` that the app's backend reads with `IPluginStorage`.
166
+ *
167
+ * Validates the prefix, the size and the file type (against the server's allow-list) before
168
+ * reading the file, then hands the bytes to the
169
+ * transport's `uploadToStorage`. Every failure (client-side or server) rejects with a
170
+ * {@link PluginStorageUploadError} whose `reason` is safe to branch on and whose `message` is the
171
+ * server's when the server answered.
172
+ *
173
+ * An `ArrayBuffer` argument is transferred to the host and detached; pass a copy to keep it.
174
+ */
175
+ declare function uploadFileToPluginStorage(transport: McpTransport, file: File | Blob | ArrayBuffer, options: UploadToStorageOptions): Promise<UploadToStorageResult>;
11
176
 
12
177
  /**
13
178
  * A single client-push event delivered from the host to a plugin surface. The host
@@ -797,4 +962,4 @@ interface UseAuthResult {
797
962
  */
798
963
  declare function useAuth(transport: McpTransport): UseAuthResult;
799
964
 
800
- export { BridgeClientContext, type ClientPushChannel, ClientPushContext, type ClientPushEvent, type ClientPushSubscribeOptions, type CreatePortMcpTransportOptions, type CreateRemoteRootOptions, type DeclarativePluginConfig, type EthisysPluginConfig, ExtensionRuntimeProvider, type ExtensionRuntimeProviderProps, type HostIdentity, HostIdentityContext, type HostIdentityUser, type HostPermission, type ItemsResponse, LocalePayload, McpTransport, PluginRealtimeContext, type PluginRealtimeSource, PortBridgeClient, type PortShim, type RemoteRoot, ThemePayload, type UseAuthResult, type UseClientPushSubscriptionOptions, type UseFrontendSessionTokenResult, type UseMcpQueryOptions, type UseMcpQueryResult, type UseMcpResourceOptions, type UseMcpResourceResult, type UseMcpToolOptions, type UseMcpToolResult, type UseModuleQueryOptions, type UseModuleQueryResult, type UseModuleToolOptions, type UseModuleToolResult, createPortMcpTransport, createRemoteRoot, decodeJwtPayload, defineDeclarativePlugin, defineEthisysPlugin, unwrapItems, useAuth, useBridgeClient, useBridgeLocale, useBridgeTheme, useClientPushSubscription, useExtensionRuntimeTransport, useFrontendSessionToken, useHostIdentity, useMcpQuery, useMcpResource, useMcpTool, useModuleQuery, useModuleTool, useOptionalExtensionRuntimeTransport, usePluginRealtimeSource };
965
+ export { BridgeClientContext, type ClientPushChannel, ClientPushContext, type ClientPushEvent, type ClientPushSubscribeOptions, type CreatePortMcpTransportOptions, type CreateRemoteRootOptions, type DeclarativePluginConfig, type EthisysPluginConfig, ExtensionRuntimeProvider, type ExtensionRuntimeProviderProps, type HostIdentity, HostIdentityContext, type HostIdentityUser, type HostPermission, type ItemsResponse, LocalePayload, McpErrorCode, McpToolError, McpTransport, PLUGIN_STORAGE_PATH_MAX_LENGTH, PLUGIN_STORAGE_PREFIX_MAX_LENGTH, PLUGIN_STORAGE_UPLOAD_CONTENT_TYPES, PLUGIN_STORAGE_UPLOAD_MAX_BYTES, PluginRealtimeContext, type PluginRealtimeSource, type PluginStorageContentTypeResolution, type PluginStoragePrefixValidation, PluginStorageUploadError, type PluginStorageUploadErrorReason, PortBridgeClient, type PortShim, type RemoteRoot, ThemePayload, type UploadToStorageOptions, UploadToStorageResult, type UseAuthResult, type UseClientPushSubscriptionOptions, type UseFrontendSessionTokenResult, type UseMcpQueryOptions, type UseMcpQueryResult, type UseMcpResourceOptions, type UseMcpResourceResult, type UseMcpToolOptions, type UseMcpToolResult, type UseModuleQueryOptions, type UseModuleQueryResult, type UseModuleToolOptions, type UseModuleToolResult, assertValidPluginStoragePrefix, createPortMcpTransport, createRemoteRoot, decodeJwtPayload, defineDeclarativePlugin, defineEthisysPlugin, isPluginStorageUploadError, pluginStorageSafeExtension, pluginStorageUploadReasonFromStatus, resolvePluginStorageContentType, toPluginStorageUploadError, unwrapItems, uploadFileToPluginStorage, useAuth, useBridgeClient, useBridgeLocale, useBridgeTheme, useClientPushSubscription, useExtensionRuntimeTransport, useFrontendSessionToken, useHostIdentity, useMcpQuery, useMcpResource, useMcpTool, useModuleQuery, useModuleTool, useOptionalExtensionRuntimeTransport, usePluginRealtimeSource, validatePluginStoragePrefix };