@jini-ai/agent-plugins 0.4.7 → 0.6.10

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 (212) hide show
  1. package/CHANGELOG.md +24 -2
  2. package/README.md +46 -0
  3. package/dist/admin-surfaces/action-dispatcher.d.ts +37 -0
  4. package/dist/admin-surfaces/action-dispatcher.d.ts.map +1 -0
  5. package/dist/admin-surfaces/action-dispatcher.js +69 -0
  6. package/dist/admin-surfaces/action-dispatcher.js.map +1 -0
  7. package/dist/admin-surfaces/action-schema.d.ts +56 -0
  8. package/dist/admin-surfaces/action-schema.d.ts.map +1 -0
  9. package/dist/admin-surfaces/action-schema.js +167 -0
  10. package/dist/admin-surfaces/action-schema.js.map +1 -0
  11. package/dist/admin-surfaces/action-tools.d.ts +40 -0
  12. package/dist/admin-surfaces/action-tools.d.ts.map +1 -0
  13. package/dist/admin-surfaces/action-tools.js +52 -0
  14. package/dist/admin-surfaces/action-tools.js.map +1 -0
  15. package/dist/admin-surfaces/callback-field-inbox.d.ts +35 -0
  16. package/dist/admin-surfaces/callback-field-inbox.d.ts.map +1 -0
  17. package/dist/admin-surfaces/callback-field-inbox.js +53 -0
  18. package/dist/admin-surfaces/callback-field-inbox.js.map +1 -0
  19. package/dist/admin-surfaces/capability-declarations.d.ts +41 -0
  20. package/dist/admin-surfaces/capability-declarations.d.ts.map +1 -0
  21. package/dist/admin-surfaces/capability-declarations.js +102 -0
  22. package/dist/admin-surfaces/capability-declarations.js.map +1 -0
  23. package/dist/admin-surfaces/contribution.d.ts +49 -0
  24. package/dist/admin-surfaces/contribution.d.ts.map +1 -0
  25. package/dist/admin-surfaces/contribution.js +30 -0
  26. package/dist/admin-surfaces/contribution.js.map +1 -0
  27. package/dist/admin-surfaces/delivery-bindings.d.ts +76 -0
  28. package/dist/admin-surfaces/delivery-bindings.d.ts.map +1 -0
  29. package/dist/admin-surfaces/delivery-bindings.js +99 -0
  30. package/dist/admin-surfaces/delivery-bindings.js.map +1 -0
  31. package/dist/admin-surfaces/descriptor.d.ts +69 -0
  32. package/dist/admin-surfaces/descriptor.d.ts.map +1 -0
  33. package/dist/admin-surfaces/descriptor.js +196 -0
  34. package/dist/admin-surfaces/descriptor.js.map +1 -0
  35. package/dist/admin-surfaces/external-links.d.ts +45 -0
  36. package/dist/admin-surfaces/external-links.d.ts.map +1 -0
  37. package/dist/admin-surfaces/external-links.js +70 -0
  38. package/dist/admin-surfaces/external-links.js.map +1 -0
  39. package/dist/admin-surfaces/host-validator.d.ts +62 -0
  40. package/dist/admin-surfaces/host-validator.d.ts.map +1 -0
  41. package/dist/admin-surfaces/host-validator.js +87 -0
  42. package/dist/admin-surfaces/host-validator.js.map +1 -0
  43. package/dist/admin-surfaces/index.d.ts +23 -0
  44. package/dist/admin-surfaces/index.d.ts.map +1 -0
  45. package/dist/admin-surfaces/index.js +21 -0
  46. package/dist/admin-surfaces/index.js.map +1 -0
  47. package/dist/admin-surfaces/protocol.d.ts +103 -0
  48. package/dist/admin-surfaces/protocol.d.ts.map +1 -0
  49. package/dist/admin-surfaces/protocol.js +25 -0
  50. package/dist/admin-surfaces/protocol.js.map +1 -0
  51. package/dist/admin-surfaces/sandbox.d.ts +78 -0
  52. package/dist/admin-surfaces/sandbox.d.ts.map +1 -0
  53. package/dist/admin-surfaces/sandbox.js +92 -0
  54. package/dist/admin-surfaces/sandbox.js.map +1 -0
  55. package/dist/admin-surfaces/settings-value.d.ts +28 -0
  56. package/dist/admin-surfaces/settings-value.d.ts.map +1 -0
  57. package/dist/admin-surfaces/settings-value.js +45 -0
  58. package/dist/admin-surfaces/settings-value.js.map +1 -0
  59. package/dist/admin-surfaces/surface-capabilities.d.ts +167 -0
  60. package/dist/admin-surfaces/surface-capabilities.d.ts.map +1 -0
  61. package/dist/admin-surfaces/surface-capabilities.js +215 -0
  62. package/dist/admin-surfaces/surface-capabilities.js.map +1 -0
  63. package/dist/admin-surfaces/surface-client.d.ts +116 -0
  64. package/dist/admin-surfaces/surface-client.d.ts.map +1 -0
  65. package/dist/admin-surfaces/surface-client.js +219 -0
  66. package/dist/admin-surfaces/surface-client.js.map +1 -0
  67. package/dist/admin-surfaces/surface-handlers.d.ts +111 -0
  68. package/dist/admin-surfaces/surface-handlers.d.ts.map +1 -0
  69. package/dist/admin-surfaces/surface-handlers.js +172 -0
  70. package/dist/admin-surfaces/surface-handlers.js.map +1 -0
  71. package/dist/admin-surfaces/theme.d.ts +59 -0
  72. package/dist/admin-surfaces/theme.d.ts.map +1 -0
  73. package/dist/admin-surfaces/theme.js +57 -0
  74. package/dist/admin-surfaces/theme.js.map +1 -0
  75. package/dist/folder-zip-node.d.ts.map +1 -0
  76. package/dist/folder-zip-node.js +59 -49
  77. package/dist/folder-zip-node.js.map +1 -0
  78. package/dist/folder-zip.d.ts.map +1 -0
  79. package/dist/folder-zip.js +9 -7
  80. package/dist/folder-zip.js.map +1 -0
  81. package/dist/index.d.ts.map +1 -0
  82. package/dist/index.js.map +1 -0
  83. package/dist/lifecycle/activation.d.ts.map +1 -0
  84. package/dist/lifecycle/activation.js.map +1 -0
  85. package/dist/lifecycle/automatic-use.d.ts +79 -0
  86. package/dist/lifecycle/automatic-use.d.ts.map +1 -0
  87. package/dist/lifecycle/automatic-use.js +165 -0
  88. package/dist/lifecycle/automatic-use.js.map +1 -0
  89. package/dist/lifecycle/bundled-digests.d.ts.map +1 -0
  90. package/dist/lifecycle/bundled-digests.js.map +1 -0
  91. package/dist/lifecycle/bundled-source-archive.d.ts.map +1 -0
  92. package/dist/lifecycle/bundled-source-archive.js.map +1 -0
  93. package/dist/lifecycle/capability-projection.d.ts.map +1 -0
  94. package/dist/lifecycle/capability-projection.js.map +1 -0
  95. package/dist/lifecycle/compatibility-metadata.d.ts +19 -0
  96. package/dist/lifecycle/compatibility-metadata.d.ts.map +1 -0
  97. package/dist/lifecycle/compatibility-metadata.js +45 -0
  98. package/dist/lifecycle/compatibility-metadata.js.map +1 -0
  99. package/dist/lifecycle/compatibility.d.ts +52 -0
  100. package/dist/lifecycle/compatibility.d.ts.map +1 -0
  101. package/dist/lifecycle/compatibility.js +60 -0
  102. package/dist/lifecycle/compatibility.js.map +1 -0
  103. package/dist/lifecycle/contribution-loader.d.ts.map +1 -0
  104. package/dist/lifecycle/contribution-loader.js.map +1 -0
  105. package/dist/lifecycle/fetch-archive.d.ts.map +1 -0
  106. package/dist/lifecycle/fetch-archive.js +26 -24
  107. package/dist/lifecycle/fetch-archive.js.map +1 -0
  108. package/dist/lifecycle/index.d.ts +14 -2
  109. package/dist/lifecycle/index.d.ts.map +1 -0
  110. package/dist/lifecycle/index.js +8 -1
  111. package/dist/lifecycle/index.js.map +1 -0
  112. package/dist/lifecycle/install-errors.d.ts.map +1 -0
  113. package/dist/lifecycle/install-errors.js.map +1 -0
  114. package/dist/lifecycle/install-from-url.d.ts.map +1 -0
  115. package/dist/lifecycle/install-from-url.js.map +1 -0
  116. package/dist/lifecycle/install.d.ts.map +1 -0
  117. package/dist/lifecycle/install.js +7 -0
  118. package/dist/lifecycle/install.js.map +1 -0
  119. package/dist/lifecycle/installed-package-index.d.ts.map +1 -0
  120. package/dist/lifecycle/installed-package-index.js +41 -29
  121. package/dist/lifecycle/installed-package-index.js.map +1 -0
  122. package/dist/lifecycle/installed-package-roots.d.ts.map +1 -0
  123. package/dist/lifecycle/installed-package-roots.js +28 -20
  124. package/dist/lifecycle/installed-package-roots.js.map +1 -0
  125. package/dist/lifecycle/layout.d.ts.map +1 -0
  126. package/dist/lifecycle/layout.js.map +1 -0
  127. package/dist/lifecycle/manifest.d.ts +13 -0
  128. package/dist/lifecycle/manifest.d.ts.map +1 -0
  129. package/dist/lifecycle/manifest.js +115 -101
  130. package/dist/lifecycle/manifest.js.map +1 -0
  131. package/dist/lifecycle/mcp-provisioning.d.ts.map +1 -0
  132. package/dist/lifecycle/mcp-provisioning.js.map +1 -0
  133. package/dist/lifecycle/node.d.ts.map +1 -0
  134. package/dist/lifecycle/node.js.map +1 -0
  135. package/dist/lifecycle/package-paths.d.ts.map +1 -0
  136. package/dist/lifecycle/package-paths.js +3 -3
  137. package/dist/lifecycle/package-paths.js.map +1 -0
  138. package/dist/lifecycle/persistent-state.d.ts.map +1 -0
  139. package/dist/lifecycle/persistent-state.js.map +1 -0
  140. package/dist/lifecycle/ports.d.ts +1 -1
  141. package/dist/lifecycle/ports.d.ts.map +1 -0
  142. package/dist/lifecycle/ports.js.map +1 -0
  143. package/dist/lifecycle/provider-contribution.d.ts +65 -0
  144. package/dist/lifecycle/provider-contribution.d.ts.map +1 -0
  145. package/dist/lifecycle/provider-contribution.js +93 -0
  146. package/dist/lifecycle/provider-contribution.js.map +1 -0
  147. package/dist/lifecycle/resolve-agent-plugin-refs.d.ts.map +1 -0
  148. package/dist/lifecycle/resolve-agent-plugin-refs.js +15 -2
  149. package/dist/lifecycle/resolve-agent-plugin-refs.js.map +1 -0
  150. package/dist/lifecycle/retire-bundled.d.ts.map +1 -0
  151. package/dist/lifecycle/retire-bundled.js +20 -18
  152. package/dist/lifecycle/retire-bundled.js.map +1 -0
  153. package/dist/lifecycle/search.d.ts +6 -1
  154. package/dist/lifecycle/search.d.ts.map +1 -0
  155. package/dist/lifecycle/search.js +45 -7
  156. package/dist/lifecycle/search.js.map +1 -0
  157. package/dist/lifecycle/seed-bundled.d.ts.map +1 -0
  158. package/dist/lifecycle/seed-bundled.js.map +1 -0
  159. package/dist/lifecycle/set-enabled.d.ts +2 -1
  160. package/dist/lifecycle/set-enabled.d.ts.map +1 -0
  161. package/dist/lifecycle/set-enabled.js +52 -8
  162. package/dist/lifecycle/set-enabled.js.map +1 -0
  163. package/dist/lifecycle/skill-file-reader.d.ts.map +1 -0
  164. package/dist/lifecycle/skill-file-reader.js +85 -71
  165. package/dist/lifecycle/skill-file-reader.js.map +1 -0
  166. package/dist/lifecycle/tools/capabilities.d.ts +199 -0
  167. package/dist/lifecycle/tools/capabilities.d.ts.map +1 -0
  168. package/dist/lifecycle/tools/capabilities.js +213 -0
  169. package/dist/lifecycle/tools/capabilities.js.map +1 -0
  170. package/dist/lifecycle/tools/definition.d.ts +32 -0
  171. package/dist/lifecycle/tools/definition.d.ts.map +1 -0
  172. package/dist/lifecycle/tools/definition.js +33 -0
  173. package/dist/lifecycle/tools/definition.js.map +1 -0
  174. package/dist/lifecycle/tools/index.d.ts +10 -0
  175. package/dist/lifecycle/tools/index.d.ts.map +1 -0
  176. package/dist/lifecycle/tools/index.js +10 -0
  177. package/dist/lifecycle/tools/index.js.map +1 -0
  178. package/dist/lifecycle/tools/manifest.d.ts +33 -0
  179. package/dist/lifecycle/tools/manifest.d.ts.map +1 -0
  180. package/dist/lifecycle/tools/manifest.js +89 -0
  181. package/dist/lifecycle/tools/manifest.js.map +1 -0
  182. package/dist/lifecycle/tools/projection.d.ts +90 -0
  183. package/dist/lifecycle/tools/projection.d.ts.map +1 -0
  184. package/dist/lifecycle/tools/projection.js +283 -0
  185. package/dist/lifecycle/tools/projection.js.map +1 -0
  186. package/dist/lifecycle/trusted-plugin-files.d.ts.map +1 -0
  187. package/dist/lifecycle/trusted-plugin-files.js.map +1 -0
  188. package/dist/lifecycle/types.d.ts +2 -0
  189. package/dist/lifecycle/types.d.ts.map +1 -0
  190. package/dist/lifecycle/types.js.map +1 -0
  191. package/dist/lifecycle/uninstall.d.ts +3 -1
  192. package/dist/lifecycle/uninstall.d.ts.map +1 -0
  193. package/dist/lifecycle/uninstall.js +51 -27
  194. package/dist/lifecycle/uninstall.js.map +1 -0
  195. package/dist/lifecycle/update-plan.d.ts +18 -0
  196. package/dist/lifecycle/update-plan.d.ts.map +1 -0
  197. package/dist/lifecycle/update-plan.js +22 -0
  198. package/dist/lifecycle/update-plan.js.map +1 -0
  199. package/dist/lifecycle/update-store.d.ts +71 -0
  200. package/dist/lifecycle/update-store.d.ts.map +1 -0
  201. package/dist/lifecycle/update-store.js +150 -0
  202. package/dist/lifecycle/update-store.js.map +1 -0
  203. package/dist/lifecycle/update.d.ts +55 -0
  204. package/dist/lifecycle/update.d.ts.map +1 -0
  205. package/dist/lifecycle/update.js +321 -0
  206. package/dist/lifecycle/update.js.map +1 -0
  207. package/dist/lifecycle/yauzl-archive-reader.d.ts.map +1 -0
  208. package/dist/lifecycle/yauzl-archive-reader.js.map +1 -0
  209. package/dist/manifest.d.ts.map +1 -0
  210. package/dist/manifest.js.map +1 -0
  211. package/package.json +39 -7
  212. package/ui-ux-design/plugin.json +7 -2
@@ -0,0 +1,196 @@
1
+ import { checkAdminSurfaceActionSchema } from './action-schema.js';
2
+ import { parseAdminSurfaceCapabilityDeclarations } from './capability-declarations.js';
3
+ /** The CSP directives a descriptor may extend. Everything else stays at the strict default. */
4
+ export const ADMIN_SURFACE_CSP_DIRECTIVES = ['script-src', 'style-src', 'img-src', 'font-src', 'connect-src', 'frame-src'];
5
+ const ID_PATTERN = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
6
+ const MAX_ID_LENGTH = 64;
7
+ const MAX_TITLE_LENGTH = 100;
8
+ const MAX_SURFACES = 16;
9
+ const MAX_FILES = 32;
10
+ const MAX_ACTIONS = 32;
11
+ const MAX_SOURCES = 8;
12
+ const MAX_LINK_ORIGINS = 8;
13
+ const MAX_RAW_BYTES = 64 * 1024;
14
+ /** One path segment: no `.`/`..`, no separators, no `%` (no encoded traversal), no leading dot. */
15
+ const SEGMENT_PATTERN = /^[A-Za-z0-9_-][A-Za-z0-9._-]*$/;
16
+ const FILE_EXTENSIONS = ['.mjs', '.js', '.css', '.json'];
17
+ /** A bare https origin with a DNS host name: no wildcard, path, query, credentials, IP or scheme keyword. */
18
+ const CSP_SOURCE_PATTERN = /^https:\/\/(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+[a-z]{2,63}(?::\d{1,5})?$/;
19
+ function isPlainObject(value) {
20
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
21
+ }
22
+ const isId = (value) => typeof value === 'string' && value.length <= MAX_ID_LENGTH && ID_PATTERN.test(value);
23
+ /** True when `value` is a relative POSIX path whose every segment is plain and that ends in one of
24
+ * `extensions`. @complexity O(n) in the path length. */
25
+ export function isContainedAdminSurfacePath(required, _optional = {}) {
26
+ const { value, extensions } = required;
27
+ if (typeof value !== 'string' || value.length > 200)
28
+ return false;
29
+ return value.split('/').every((segment) => SEGMENT_PATTERN.test(segment)) && extensions.some((extension) => value.endsWith(extension));
30
+ }
31
+ /** True when `value` is a CSP source this protocol allows a plugin to add.
32
+ * @complexity O(n) in the source length. */
33
+ export function isAllowedAdminSurfaceCspSource(required, _optional = {}) {
34
+ const { value } = required;
35
+ if (typeof value !== 'string' || !CSP_SOURCE_PATTERN.test(value))
36
+ return false;
37
+ // The URL parser normalizes default ports and IDNA forms; anything it rewrites is not a bare origin.
38
+ return new URL(value).origin === value;
39
+ }
40
+ /**
41
+ * Parses the contribution file. One invalid surface refuses the whole file (the loader reports it).
42
+ * @complexity O(s * (f + a + c)) surfaces with their files, actions and CSP sources; input bounded to 64 KiB.
43
+ */
44
+ export function parseAdminSurfacesFile(required, _optional = {}) {
45
+ if (required.raw.length > MAX_RAW_BYTES)
46
+ return { ok: false, reason: 'larger than 64 KiB' };
47
+ let value;
48
+ try {
49
+ value = JSON.parse(required.raw);
50
+ }
51
+ catch {
52
+ return { ok: false, reason: 'not valid JSON' };
53
+ }
54
+ if (!isPlainObject(value) || value.schemaVersion !== 1)
55
+ return { ok: false, reason: 'schemaVersion must be 1' };
56
+ const descriptors = parseSurfaces(value.surfaces);
57
+ return typeof descriptors === 'string' ? { ok: false, reason: descriptors } : { ok: true, descriptors };
58
+ }
59
+ function parseSurfaces(surfaces) {
60
+ if (!Array.isArray(surfaces) || surfaces.length > MAX_SURFACES)
61
+ return `surfaces must be an array of at most ${MAX_SURFACES}`;
62
+ const descriptors = [];
63
+ for (const [index, entry] of surfaces.entries()) {
64
+ const parsed = parseSurface(entry, `surfaces[${index}]`);
65
+ if (typeof parsed === 'string')
66
+ return parsed;
67
+ if (descriptors.some((seen) => seen.id === parsed.id))
68
+ return `surfaces[${index}].id '${parsed.id}' is declared twice`;
69
+ descriptors.push(parsed);
70
+ }
71
+ return descriptors;
72
+ }
73
+ function parseSurface(entry, at) {
74
+ if (!isPlainObject(entry))
75
+ return `${at} must be an object`;
76
+ const identity = parseIdentity(entry, at);
77
+ if (typeof identity === 'string')
78
+ return identity;
79
+ const files = parseFiles(entry.files ?? [], at);
80
+ if (typeof files === 'string')
81
+ return files;
82
+ const actions = parseActions(entry.actions ?? [], at);
83
+ if (typeof actions === 'string')
84
+ return actions;
85
+ return parseSurfaceExtras(entry, { ...identity, files, actions }, at);
86
+ }
87
+ /** The CSP extensions, the optional link origins and the optional handler fields, after the core fields parsed. */
88
+ function parseSurfaceExtras(entry, surface, at) {
89
+ const csp = parseCsp(entry.csp ?? {}, at);
90
+ if (typeof csp === 'string')
91
+ return csp;
92
+ const linkOrigins = entry.linkOrigins === undefined ? undefined : parseLinkOrigins(entry.linkOrigins, `${at}.linkOrigins`);
93
+ if (typeof linkOrigins === 'string')
94
+ return linkOrigins;
95
+ const handler = parseHandler(entry, surface, at);
96
+ return typeof handler === 'string' ? handler : { ...surface, csp, ...(linkOrigins && { linkOrigins }), ...handler };
97
+ }
98
+ /** At most 8 unique bare https origins, by the CSP source rule: a link the host opens leaves the sandbox. */
99
+ function parseLinkOrigins(value, at) {
100
+ if (!Array.isArray(value) || value.length > MAX_LINK_ORIGINS)
101
+ return `${at} must be an array of at most ${MAX_LINK_ORIGINS}`;
102
+ const bad = value.findIndex((origin, index) => !isAllowedAdminSurfaceCspSource({ value: origin }) || value.indexOf(origin) !== index);
103
+ return bad === -1 ? value : `${at}[${bad}] must be a unique bare https origin (no wildcards, paths or keywords)`;
104
+ }
105
+ function parseHandler(entry, surface, at) {
106
+ const { handlerModule } = entry;
107
+ if (handlerModule === undefined)
108
+ return handlerOnlyFieldRefusal(entry, at) ?? {};
109
+ if (!isContainedAdminSurfacePath({ value: handlerModule, extensions: ['.mjs'] }))
110
+ return `${at}.handlerModule must be a plain relative path ending in .mjs`;
111
+ if (surface.files.includes(handlerModule))
112
+ return `${at}.handlerModule is server code and may not also be served to the frame`;
113
+ const unchecked = surface.actions.findIndex((action) => action.result === undefined);
114
+ if (unchecked !== -1)
115
+ return `${at}.actions[${unchecked}] must declare a result schema when the surface has a handlerModule`;
116
+ const declarations = parseAdminSurfaceCapabilityDeclarations({ entry, at });
117
+ if (typeof declarations === 'string')
118
+ return declarations;
119
+ const handler = parseBootstrap(entry.bootstrap, handlerModule, at);
120
+ return typeof handler === 'string' ? handler : { ...handler, ...declarations };
121
+ }
122
+ /** Fields only a handler module can use; without one they would be dead declarations. */
123
+ function handlerOnlyFieldRefusal(entry, at) {
124
+ if (entry.bootstrap !== undefined)
125
+ return `${at}.bootstrap needs a handlerModule that provides it`;
126
+ const declared = ['connections', 'publicConfig', 'deliveryAdapters', 'forms'].find((name) => entry[name] !== undefined);
127
+ return declared === undefined ? null : `${at}.${declared} needs a handlerModule that uses it`;
128
+ }
129
+ function parseBootstrap(bootstrap, handlerModule, at) {
130
+ if (bootstrap === undefined)
131
+ return { handlerModule };
132
+ const reason = checkAdminSurfaceActionSchema({ schema: bootstrap });
133
+ return reason === null ? { handlerModule, bootstrap: bootstrap } : `${at}.bootstrap ${reason}`;
134
+ }
135
+ function parseIdentity(entry, at) {
136
+ const { id, title, entry: html } = entry;
137
+ if (!isId(id))
138
+ return `${at}.id must be a lowercase hyphenated id`;
139
+ if (typeof title !== 'string' || !title.trim() || title.length > MAX_TITLE_LENGTH)
140
+ return `${at}.title must be a non-empty string of at most ${MAX_TITLE_LENGTH} characters`;
141
+ if (!isContainedAdminSurfacePath({ value: html, extensions: ['.html'] }))
142
+ return `${at}.entry must be a plain relative path ending in .html`;
143
+ return { id, title, entry: html };
144
+ }
145
+ function parseFiles(value, at) {
146
+ if (!Array.isArray(value) || value.length > MAX_FILES)
147
+ return `${at}.files must be an array of at most ${MAX_FILES}`;
148
+ const bad = value.findIndex((file) => !isContainedAdminSurfacePath({ value: file, extensions: FILE_EXTENSIONS }));
149
+ return bad === -1 ? value : `${at}.files[${bad}] must be a plain relative path ending in ${FILE_EXTENSIONS.join(', ')}`;
150
+ }
151
+ function parseActions(value, at) {
152
+ if (!Array.isArray(value) || value.length > MAX_ACTIONS)
153
+ return `${at}.actions must be an array of at most ${MAX_ACTIONS}`;
154
+ const actions = [];
155
+ for (const [index, action] of value.entries()) {
156
+ const parsed = parseAction(action, `${at}.actions[${index}]`);
157
+ if (typeof parsed === 'string')
158
+ return parsed;
159
+ if (actions.some((seen) => seen.name === parsed.name))
160
+ return `${at}.actions[${index}].name '${parsed.name}' is declared twice`;
161
+ actions.push(parsed);
162
+ }
163
+ return actions;
164
+ }
165
+ function parseAction(action, at) {
166
+ if (!isPlainObject(action))
167
+ return `${at} must be an object`;
168
+ if (!isId(action.name))
169
+ return `${at}.name must be a lowercase hyphenated id`;
170
+ const effect = action.effect === undefined ? 'write' : action.effect;
171
+ if (effect !== 'read' && effect !== 'write' && effect !== 'destructive')
172
+ return `${at}.effect must be read, write or destructive`;
173
+ const input = checkAdminSurfaceActionSchema({ schema: action.input });
174
+ if (input !== null)
175
+ return `${at}.input ${input}`;
176
+ if (action.result === undefined)
177
+ return { name: action.name, effect, input: action.input };
178
+ const result = checkAdminSurfaceActionSchema({ schema: action.result });
179
+ if (result !== null)
180
+ return `${at}.result ${result}`;
181
+ return { name: action.name, effect, input: action.input, result: action.result };
182
+ }
183
+ function parseCsp(value, at) {
184
+ if (!isPlainObject(value))
185
+ return `${at}.csp must be an object`;
186
+ for (const [directive, sources] of Object.entries(value)) {
187
+ if (!ADMIN_SURFACE_CSP_DIRECTIVES.includes(directive))
188
+ return `${at}.csp may not extend '${directive.slice(0, 32)}'`;
189
+ if (!Array.isArray(sources) || sources.length > MAX_SOURCES)
190
+ return `${at}.csp['${directive}'] must be an array of at most ${MAX_SOURCES}`;
191
+ if (!sources.every((source) => isAllowedAdminSurfaceCspSource({ value: source })))
192
+ return `${at}.csp['${directive}'] may only list bare https origins (no wildcards, paths or keywords)`;
193
+ }
194
+ return value;
195
+ }
196
+ //# sourceMappingURL=descriptor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"descriptor.js","sourceRoot":"","sources":["../../src/admin-surfaces/descriptor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,45 @@
1
+ /**
2
+ * @file Host-mediated external links: a surface declares the https origins it may link to
3
+ * (`linkOrigins`, parsed in `./descriptor.ts`), and asks the host page to open a URL with an `open-link` message; the host page
4
+ * passes that message to `openAdminSurfaceLink`, which opens it through the host's own opener only
5
+ * when it comes from this mount and names a declared https origin.
6
+ *
7
+ * Why the host opens links: a surface frame is sandboxed without `allow-popups` or top navigation,
8
+ * so it cannot open anything itself, and must not: the host decides HOW (a new tab with `noopener`
9
+ * on the web, the system browser on desktop). Why the gate is this strict: a link the host opens
10
+ * leaves the sandbox entirely, so the destination is limited to what the shipped, digest-checked
11
+ * surfaces file declared, and the opener receives the URL parser's normalized form so it never
12
+ * re-parses a string this gate judged differently.
13
+ */
14
+ import { type AdminSurfaceMessageEvent, type AdminSurfaceMountRecord } from './host-validator.js';
15
+ import { type AdminSurfaceActionResponse } from './protocol.js';
16
+ /** Host port: opens an already-checked https URL however the host decides (new tab with `noopener`, system browser). */
17
+ export type AdminSurfaceOpenLinkPort = (required: {
18
+ readonly url: string;
19
+ }, optional?: Record<string, never>) => void | Promise<void>;
20
+ /** `ignored`: not this mount's open-link message; drop silently. Otherwise post `response` back to the frame. */
21
+ export type AdminSurfaceLinkVerdict = {
22
+ readonly ok: true;
23
+ readonly url: string;
24
+ readonly response: AdminSurfaceActionResponse;
25
+ } | {
26
+ readonly ok: false;
27
+ readonly ignored: string;
28
+ } | {
29
+ readonly ok: false;
30
+ readonly refused: string;
31
+ readonly response: AdminSurfaceActionResponse;
32
+ };
33
+ /**
34
+ * Judges one `message` event as an open-link request for one mount and, when it passes, opens it
35
+ * through the host's port. Pass every message event here as well as to `validateAdminSurfaceMessage`;
36
+ * each ignores the other's messages.
37
+ * @param required.openLink - The host's opener; called at most once, with the normalized URL.
38
+ * @complexity O(n) in the URL length, plus the opener.
39
+ */
40
+ export declare function openAdminSurfaceLink(required: {
41
+ readonly event: AdminSurfaceMessageEvent;
42
+ readonly mount: AdminSurfaceMountRecord;
43
+ readonly openLink: AdminSurfaceOpenLinkPort;
44
+ }, _optional?: Record<string, never>): Promise<AdminSurfaceLinkVerdict>;
45
+ //# sourceMappingURL=external-links.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"external-links.d.ts","sourceRoot":"","sources":["../../src/admin-surfaces/external-links.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,EAA6C,KAAK,wBAAwB,EAAE,KAAK,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AAC7I,OAAO,EAEL,KAAK,0BAA0B,EAChC,MAAM,eAAe,CAAC;AAKvB,wHAAwH;AACxH,MAAM,MAAM,wBAAwB,GAAG,CAAC,QAAQ,EAAE;IAAE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;CAAE,EAAE,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAEtI,iHAAiH;AACjH,MAAM,MAAM,uBAAuB,GAC/B;IAAE,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,0BAA0B,CAAA;CAAE,GAC1F;IAAE,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAChD;IAAE,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,0BAA0B,CAAA;CAAE,CAAC;AAuBpG;;;;;;GAMG;AACH,wBAAsB,oBAAoB,CACxC,QAAQ,EAAE;IAAE,QAAQ,CAAC,KAAK,EAAE,wBAAwB,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,uBAAuB,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,wBAAwB,CAAA;CAAE,EAC5I,SAAS,GAAE,MAAM,CAAC,MAAM,EAAE,KAAK,CAAM,GACpC,OAAO,CAAC,uBAAuB,CAAC,CAYlC"}
@@ -0,0 +1,70 @@
1
+ /**
2
+ * @file Host-mediated external links: a surface declares the https origins it may link to
3
+ * (`linkOrigins`, parsed in `./descriptor.ts`), and asks the host page to open a URL with an `open-link` message; the host page
4
+ * passes that message to `openAdminSurfaceLink`, which opens it through the host's own opener only
5
+ * when it comes from this mount and names a declared https origin.
6
+ *
7
+ * Why the host opens links: a surface frame is sandboxed without `allow-popups` or top navigation,
8
+ * so it cannot open anything itself, and must not: the host decides HOW (a new tab with `noopener`
9
+ * on the web, the system browser on desktop). Why the gate is this strict: a link the host opens
10
+ * leaves the sandbox entirely, so the destination is limited to what the shipped, digest-checked
11
+ * surfaces file declared, and the opener receives the URL parser's normalized form so it never
12
+ * re-parses a string this gate judged differently.
13
+ */
14
+ import { frameTransportRefusal, REQUEST_ID_PATTERN } from './host-validator.js';
15
+ import { ADMIN_SURFACE_PROTOCOL, ADMIN_SURFACE_PROTOCOL_VERSION, adminSurfaceActionResponse, } from './protocol.js';
16
+ /** Longer URLs are refused, not cut: a truncated link would open somewhere the plugin did not mean. */
17
+ const MAX_LINK_URL_LENGTH = 2048;
18
+ function isOpenLinkEnvelope(data) {
19
+ if (typeof data !== 'object' || data === null)
20
+ return false;
21
+ const message = data;
22
+ const isProtocol = message.protocol === ADMIN_SURFACE_PROTOCOL && message.version === ADMIN_SURFACE_PROTOCOL_VERSION && message.kind === 'open-link';
23
+ return isProtocol && typeof message.mountId === 'string' && typeof message.requestId === 'string' && REQUEST_ID_PATTERN.test(message.requestId) && typeof message.url === 'string';
24
+ }
25
+ /** The normalized URL when `raw` may be opened, or why not. Messages never echo the URL. @complexity O(n) in the URL length. */
26
+ function checkLink(raw, origins) {
27
+ if (raw.length > MAX_LINK_URL_LENGTH)
28
+ return { code: 'link-too-long', message: 'The link is too long.' };
29
+ if (!URL.canParse(raw))
30
+ return { code: 'link-invalid', message: 'That link is not a valid web address.' };
31
+ const parsed = new URL(raw);
32
+ if (parsed.protocol !== 'https:')
33
+ return { code: 'link-not-https', message: 'Only https links can be opened.' };
34
+ // Credentials in a link are a phishing shape (`https://trusted@elsewhere`) and never needed to open a page.
35
+ if (parsed.username !== '' || parsed.password !== '')
36
+ return { code: 'link-invalid', message: 'That link is not a valid web address.' };
37
+ if (!origins.includes(parsed.origin))
38
+ return { code: 'link-undeclared', message: 'This surface did not declare that link destination.' };
39
+ return { url: parsed.href };
40
+ }
41
+ /**
42
+ * Judges one `message` event as an open-link request for one mount and, when it passes, opens it
43
+ * through the host's port. Pass every message event here as well as to `validateAdminSurfaceMessage`;
44
+ * each ignores the other's messages.
45
+ * @param required.openLink - The host's opener; called at most once, with the normalized URL.
46
+ * @complexity O(n) in the URL length, plus the opener.
47
+ */
48
+ export async function openAdminSurfaceLink(required, _optional = {}) {
49
+ const { event, mount, openLink } = required;
50
+ const transport = frameTransportRefusal({ event, mount });
51
+ if (transport !== null)
52
+ return { ok: false, ignored: transport };
53
+ if (!isOpenLinkEnvelope(event.data))
54
+ return { ok: false, ignored: 'not-an-open-link' };
55
+ const request = event.data;
56
+ if (request.mountId !== mount.mountId)
57
+ return { ok: false, ignored: 'mount-mismatch' };
58
+ const refuse = (refusal, retryable = false) => ({ ok: false, refused: refusal.code, response: adminSurfaceActionResponse({ request, outcome: { ok: false, error: { ...refusal, retryable } } }) });
59
+ const checked = checkLink(request.url, mount.descriptor.linkOrigins ?? []);
60
+ if (!('url' in checked))
61
+ return refuse(checked);
62
+ try {
63
+ await openLink({ url: checked.url });
64
+ }
65
+ catch {
66
+ return refuse({ code: 'link-failed', message: 'The host could not open the link. Try again.' }, true);
67
+ }
68
+ return { ok: true, url: checked.url, response: adminSurfaceActionResponse({ request, outcome: { ok: true, result: null } }) };
69
+ }
70
+ //# sourceMappingURL=external-links.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"external-links.js","sourceRoot":"","sources":["../../src/admin-surfaces/external-links.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,62 @@
1
+ import type { AdminSurfaceDescriptor } from './descriptor.js';
2
+ import { type AdminSurfaceActionRequest, type AdminSurfaceActionResponse } from './protocol.js';
3
+ /** The fields of a `MessageEvent` the gate reads; a real event satisfies it structurally. */
4
+ export interface AdminSurfaceMessageEvent {
5
+ readonly origin: string;
6
+ readonly source: unknown;
7
+ readonly data: unknown;
8
+ }
9
+ export interface AdminSurfaceMountRecord {
10
+ readonly mountId: string;
11
+ /** The frame's `contentWindow`; the event's `source` must be this exact object. */
12
+ readonly frame: unknown;
13
+ /** `linkOrigins` matters only to `openAdminSurfaceLink`; a record without it opens no links. */
14
+ readonly descriptor: Pick<AdminSurfaceDescriptor, 'actions' | 'linkOrigins'>;
15
+ }
16
+ /** `ignored`: not addressed to this mount; drop silently. `refused`: this mount's request was invalid;
17
+ * post `response` back so the surface can show why. */
18
+ export type AdminSurfaceMessageVerdict = {
19
+ readonly ok: true;
20
+ readonly request: AdminSurfaceActionRequest;
21
+ } | {
22
+ readonly ok: false;
23
+ readonly ignored: string;
24
+ } | {
25
+ readonly ok: false;
26
+ readonly refused: string;
27
+ readonly response: AdminSurfaceActionResponse;
28
+ };
29
+ export declare const REQUEST_ID_PATTERN: RegExp;
30
+ /** Character length of the payload as JSON, or Infinity when it is not JSON-serializable. */
31
+ /** Whether `event` comes from `mount`'s frame at all (origin and window), for every inbound message kind.
32
+ * @returns The failed check, or `null`. @complexity O(1). */
33
+ export declare function frameTransportRefusal(required: {
34
+ readonly event: AdminSurfaceMessageEvent;
35
+ readonly mount: Pick<AdminSurfaceMountRecord, 'frame'>;
36
+ }, _optional?: Record<string, never>): string | null;
37
+ /**
38
+ * Judges one `message` event against one mount.
39
+ * @complexity O(p) in the payload size (one JSON measure plus one schema walk).
40
+ */
41
+ export declare function validateAdminSurfaceMessage(required: {
42
+ readonly event: AdminSurfaceMessageEvent;
43
+ readonly mount: AdminSurfaceMountRecord;
44
+ }, _optional?: Record<string, never>): AdminSurfaceMessageVerdict;
45
+ /** Frame heights a host accepts by default (CSS px): tall enough for a notice, short enough that a
46
+ * surface cannot push the admin page out of reach. */
47
+ export declare const ADMIN_SURFACE_MIN_HEIGHT = 96;
48
+ export declare const ADMIN_SURFACE_MAX_HEIGHT = 4000;
49
+ /**
50
+ * The frame height `event` asks for when it is `mount`'s own `resize` message (same origin, window and
51
+ * mount as every other inbound message), clamped to `[min, max]`; null for anything else, which the
52
+ * caller ignores. A size is cosmetic, so a bad one is dropped rather than answered.
53
+ * @complexity O(1).
54
+ */
55
+ export declare function readAdminSurfaceResize(required: {
56
+ readonly event: AdminSurfaceMessageEvent;
57
+ readonly mount: Pick<AdminSurfaceMountRecord, 'mountId' | 'frame'>;
58
+ }, optional?: {
59
+ readonly min?: number;
60
+ readonly max?: number;
61
+ }): number | null;
62
+ //# sourceMappingURL=host-validator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"host-validator.d.ts","sourceRoot":"","sources":["../../src/admin-surfaces/host-validator.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AAC9D,OAAO,EAEuB,KAAK,yBAAyB,EAAE,KAAK,0BAA0B,EAC5F,MAAM,eAAe,CAAC;AAEvB,6FAA6F;AAC7F,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,mFAAmF;IACnF,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,gGAAgG;IAChG,QAAQ,CAAC,UAAU,EAAE,IAAI,CAAC,sBAAsB,EAAE,SAAS,GAAG,aAAa,CAAC,CAAC;CAC9E;AAED;uDACuD;AACvD,MAAM,MAAM,0BAA0B,GAClC;IAAE,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,yBAAyB,CAAA;CAAE,GAClE;IAAE,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAChD;IAAE,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,0BAA0B,CAAA;CAAE,CAAC;AAEpG,eAAO,MAAM,kBAAkB,QAA0B,CAAC;AAc1D,6FAA6F;AAC7F;6DAC6D;AAC7D,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE;IAAE,QAAQ,CAAC,KAAK,EAAE,wBAAwB,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,IAAI,CAAC,uBAAuB,EAAE,OAAO,CAAC,CAAA;CAAE,EAAE,SAAS,GAAE,MAAM,CAAC,MAAM,EAAE,KAAK,CAAM,GAAG,MAAM,GAAG,IAAI,CAK1M;AAUD;;;GAGG;AACH,wBAAgB,2BAA2B,CAAC,QAAQ,EAAE;IAAE,QAAQ,CAAC,KAAK,EAAE,wBAAwB,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,uBAAuB,CAAA;CAAE,EAAE,SAAS,GAAE,MAAM,CAAC,MAAM,EAAE,KAAK,CAAM,GAAG,0BAA0B,CAY9M;AAED;uDACuD;AACvD,eAAO,MAAM,wBAAwB,KAAK,CAAC;AAC3C,eAAO,MAAM,wBAAwB,OAAO,CAAC;AAS7C;;;;;GAKG;AACH,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE;IAAE,QAAQ,CAAC,KAAK,EAAE,wBAAwB,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,IAAI,CAAC,uBAAuB,EAAE,SAAS,GAAG,OAAO,CAAC,CAAA;CAAE,EAC1H,QAAQ,GAAE;IAAE,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAO,GAC9D,MAAM,GAAG,IAAI,CAMf"}
@@ -0,0 +1,87 @@
1
+ /**
2
+ * @file The host page's gate for messages arriving from a mounted admin surface frame.
3
+ *
4
+ * Why every check is needed: all sandboxed frames share the origin "null", so the origin check only
5
+ * proves "some sandboxed frame"; the window identity proves it is THIS mount's
6
+ * frame; the nonce proves the frame still runs the document the host initialized (a navigated frame
7
+ * never received it). Action and schema checks here are an early refusal for the person using the
8
+ * surface; the server-side dispatcher repeats them because a host route can be called directly.
9
+ */
10
+ import { exceedsAdminSurfacePayloadLimit, validateAdminSurfaceActionValue } from './action-schema.js';
11
+ import { ADMIN_SURFACE_PROTOCOL, ADMIN_SURFACE_PROTOCOL_VERSION, SANDBOXED_FRAME_ORIGIN, adminSurfaceActionResponse, } from './protocol.js';
12
+ export const REQUEST_ID_PATTERN = /^[A-Za-z0-9_-]{1,64}$/;
13
+ function isRequestEnvelope(data) {
14
+ if (typeof data !== 'object' || data === null)
15
+ return false;
16
+ const message = data;
17
+ const isProtocol = message.protocol === ADMIN_SURFACE_PROTOCOL && message.version === ADMIN_SURFACE_PROTOCOL_VERSION && message.kind === 'action-request';
18
+ return isProtocol && hasRequestFields(message);
19
+ }
20
+ function hasRequestFields(message) {
21
+ return typeof message.mountId === 'string' && typeof message.requestId === 'string' && REQUEST_ID_PATTERN.test(message.requestId)
22
+ && typeof message.action === 'string' && Object.hasOwn(message, 'payload');
23
+ }
24
+ /** Character length of the payload as JSON, or Infinity when it is not JSON-serializable. */
25
+ /** Whether `event` comes from `mount`'s frame at all (origin and window), for every inbound message kind.
26
+ * @returns The failed check, or `null`. @complexity O(1). */
27
+ export function frameTransportRefusal(required, _optional = {}) {
28
+ const { event, mount } = required;
29
+ // "null" is the origin of every frame sandboxed with `allow-scripts` only; nothing else may speak for a mount.
30
+ if (event.origin !== SANDBOXED_FRAME_ORIGIN)
31
+ return 'origin-mismatch';
32
+ return event.source === mount.frame ? null : 'source-mismatch';
33
+ }
34
+ /** Which transport check `event` fails for `mount`, or `null` when it is this mount's well-formed request. */
35
+ function transportRefusal(event, mount) {
36
+ const frame = frameTransportRefusal({ event, mount });
37
+ if (frame !== null)
38
+ return frame;
39
+ if (!isRequestEnvelope(event.data))
40
+ return 'not-an-action-request';
41
+ return event.data.mountId === mount.mountId ? null : 'mount-mismatch';
42
+ }
43
+ /**
44
+ * Judges one `message` event against one mount.
45
+ * @complexity O(p) in the payload size (one JSON measure plus one schema walk).
46
+ */
47
+ export function validateAdminSurfaceMessage(required, _optional = {}) {
48
+ const { event, mount } = required;
49
+ const ignored = transportRefusal(event, mount);
50
+ if (ignored !== null)
51
+ return { ok: false, ignored };
52
+ const request = event.data;
53
+ const refuse = (code, message) => ({ ok: false, refused: code, response: adminSurfaceActionResponse({ request, outcome: { ok: false, error: { code, message, retryable: false } } }) });
54
+ const action = mount.descriptor.actions.find((declared) => declared.name === request.action);
55
+ if (action === undefined)
56
+ return refuse('action-undeclared', 'This surface did not declare that action.');
57
+ if (exceedsAdminSurfacePayloadLimit({ payload: request.payload }))
58
+ return refuse('invalid-payload', 'The request is too large.');
59
+ const violation = validateAdminSurfaceActionValue({ schema: action.input, value: request.payload });
60
+ if (violation !== null)
61
+ return refuse('invalid-payload', `The request does not match the action's input: ${violation}.`);
62
+ return { ok: true, request };
63
+ }
64
+ /** Frame heights a host accepts by default (CSS px): tall enough for a notice, short enough that a
65
+ * surface cannot push the admin page out of reach. */
66
+ export const ADMIN_SURFACE_MIN_HEIGHT = 96;
67
+ export const ADMIN_SURFACE_MAX_HEIGHT = 4000;
68
+ function isResizeForMount({ message, mountId }, _options = {}) {
69
+ const isResize = message.protocol === ADMIN_SURFACE_PROTOCOL && message.version === ADMIN_SURFACE_PROTOCOL_VERSION && message.kind === 'resize';
70
+ return isResize && message.mountId === mountId;
71
+ }
72
+ /**
73
+ * The frame height `event` asks for when it is `mount`'s own `resize` message (same origin, window and
74
+ * mount as every other inbound message), clamped to `[min, max]`; null for anything else, which the
75
+ * caller ignores. A size is cosmetic, so a bad one is dropped rather than answered.
76
+ * @complexity O(1).
77
+ */
78
+ export function readAdminSurfaceResize(required, optional = {}) {
79
+ const { event, mount } = required;
80
+ if (frameTransportRefusal({ event, mount }) !== null || typeof event.data !== 'object' || event.data === null)
81
+ return null;
82
+ const message = event.data;
83
+ if (!isResizeForMount({ message, mountId: mount.mountId }) || typeof message.height !== 'number' || !Number.isFinite(message.height))
84
+ return null;
85
+ return Math.min(optional.max ?? ADMIN_SURFACE_MAX_HEIGHT, Math.max(optional.min ?? ADMIN_SURFACE_MIN_HEIGHT, Math.ceil(message.height)));
86
+ }
87
+ //# sourceMappingURL=host-validator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"host-validator.js","sourceRoot":"","sources":["../../src/admin-surfaces/host-validator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * @file Public barrel for `@jini-ai/agent-plugins/admin-surfaces`: plugin-owned admin surfaces
3
+ * (sandboxed iframes) and the host-mediated action protocol. See `./README.md`.
4
+ *
5
+ * Explicit on purpose: only what a host composes is public. The parsers, checkers and message
6
+ * constants behind these entry points stay internal, so they can change without a host noticing.
7
+ */
8
+ export { adminSurfaceInitMessage, adminSurfaceActionResponse, type AdminSurfaceBootstrap, type AdminSurfaceInitMessage, type AdminSurfaceActionRequest, type AdminSurfaceActionFailure, type AdminSurfaceActionOutcome, type AdminSurfaceActionResponse, type AdminSurfaceOpenLinkRequest, type AdminSurfaceResizeMessage, } from './protocol.js';
9
+ export { readAdminSurfaceTheme, adminSurfaceThemeMessage, ADMIN_SURFACE_THEME_TOKENS, type AdminSurfaceTheme, type AdminSurfaceThemeToken, type AdminSurfaceColorScheme, type AdminSurfaceThemeMessage, } from './theme.js';
10
+ export type { AdminSurfaceActionSchema } from './action-schema.js';
11
+ export { parseAdminSurfacesFile, type AdminSurfaceCspDirective, type AdminSurfaceAction, type AdminSurfaceDescriptor } from './descriptor.js';
12
+ export { adminSurfaceFrameAttributes, createAdminSurfaceMount, createAdminSurfaceBootstrap, adminSurfaceBootstrapHeaders } from './sandbox.js';
13
+ export { validateAdminSurfaceMessage, readAdminSurfaceResize, ADMIN_SURFACE_MIN_HEIGHT, ADMIN_SURFACE_MAX_HEIGHT, type AdminSurfaceMessageEvent, type AdminSurfaceMountRecord, type AdminSurfaceMessageVerdict, } from './host-validator.js';
14
+ export { createAdminSurfaceActionDispatcher, AdminSurfaceActionError, type AdminSurfaceActionHandler } from './action-dispatcher.js';
15
+ export { defineAdminSurfaceContribution, readAdminSurfaceFile, type LoadedAdminSurface } from './contribution.js';
16
+ export { defineAdminSurfaceHandlerContribution, createAdminSurfaceHandlerHost, type AdminSurfaceHandlerContext, type AdminSurfacePluginContext, type AdminSurfaceBootstrapCall, type AdminSurfaceHandlerCall, type AdminSurfaceHandlerModule, type LoadedAdminSurfaceHandlers, type AdminSurfaceHostKind, } from './surface-handlers.js';
17
+ export type { AdminSurfaceConnectionDeclaration, AdminSurfaceCapabilityDeclarations } from './capability-declarations.js';
18
+ export { ADMIN_SURFACE_ACTION_INTENTS, ADMIN_SURFACE_STATE_LIMITS, type AdminSurfaceConnectionState, type AdminSurfaceConnectionAction, type AdminSurfaceRevocationOutcome, type AdminSurfaceConnectionStatus, type AdminSurfaceSignInAttempt, type AdminSurfaceAuthorizationStart, type AdminSurfaceConnections, type AdminSurfaceStateValue, type AdminSurfaceState, type AdminSurfacePublicConfig, type AdminSurfaceForm, type AdminSurfaceForms, type AdminSurfaceCapabilities, type AdminSurfaceCapabilitiesPort, } from './surface-capabilities.js';
19
+ export type { AdminSurfaceDeliveryBinding, AdminSurfaceDeliveryBindingDraft, AdminSurfaceDeliveryBindingForms, AdminSurfaceDeliveryBindings, } from './delivery-bindings.js';
20
+ export { openAdminSurfaceLink, type AdminSurfaceOpenLinkPort, type AdminSurfaceLinkVerdict } from './external-links.js';
21
+ export { createAdminSurfaceCallbackInbox, type AdminSurfaceCallbackFieldKey } from './callback-field-inbox.js';
22
+ export { buildAdminSurfaceActionTools, type AdminSurfaceToolSource, type AdminSurfaceToolContext } from './action-tools.js';
23
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/admin-surfaces/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EACL,uBAAuB,EAAE,0BAA0B,EACnD,KAAK,qBAAqB,EAAE,KAAK,uBAAuB,EAAE,KAAK,yBAAyB,EAAE,KAAK,yBAAyB,EACxH,KAAK,yBAAyB,EAAE,KAAK,0BAA0B,EAAE,KAAK,2BAA2B,EAAE,KAAK,yBAAyB,GAClI,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,qBAAqB,EAAE,wBAAwB,EAAE,0BAA0B,EAC3E,KAAK,iBAAiB,EAAE,KAAK,sBAAsB,EAAE,KAAK,uBAAuB,EAAE,KAAK,wBAAwB,GACjH,MAAM,YAAY,CAAC;AACpB,YAAY,EAAE,wBAAwB,EAAE,MAAM,oBAAoB,CAAC;AACnE,OAAO,EAAE,sBAAsB,EAAE,KAAK,wBAAwB,EAAE,KAAK,kBAAkB,EAAE,KAAK,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AAC9I,OAAO,EAAE,2BAA2B,EAAE,uBAAuB,EAAE,2BAA2B,EAAE,4BAA4B,EAAE,MAAM,cAAc,CAAC;AAC/I,OAAO,EACL,2BAA2B,EAAE,sBAAsB,EAAE,wBAAwB,EAAE,wBAAwB,EACvG,KAAK,wBAAwB,EAAE,KAAK,uBAAuB,EAAE,KAAK,0BAA0B,GAC7F,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAAE,kCAAkC,EAAE,uBAAuB,EAAE,KAAK,yBAAyB,EAAE,MAAM,wBAAwB,CAAC;AACrI,OAAO,EAAE,8BAA8B,EAAE,oBAAoB,EAAE,KAAK,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAClH,OAAO,EACL,qCAAqC,EAAE,6BAA6B,EACpE,KAAK,0BAA0B,EAAE,KAAK,yBAAyB,EAAE,KAAK,yBAAyB,EAAE,KAAK,uBAAuB,EAC7H,KAAK,yBAAyB,EAAE,KAAK,0BAA0B,EAAE,KAAK,oBAAoB,GAC3F,MAAM,uBAAuB,CAAC;AAC/B,YAAY,EAAE,iCAAiC,EAAE,kCAAkC,EAAE,MAAM,8BAA8B,CAAC;AAC1H,OAAO,EACL,4BAA4B,EAAE,0BAA0B,EACxD,KAAK,2BAA2B,EAAE,KAAK,4BAA4B,EAAE,KAAK,6BAA6B,EAAE,KAAK,4BAA4B,EAAE,KAAK,yBAAyB,EAC1K,KAAK,8BAA8B,EAAE,KAAK,uBAAuB,EAAE,KAAK,sBAAsB,EAAE,KAAK,iBAAiB,EACtH,KAAK,wBAAwB,EAAE,KAAK,gBAAgB,EAAE,KAAK,iBAAiB,EAAE,KAAK,wBAAwB,EAAE,KAAK,4BAA4B,GAC/I,MAAM,2BAA2B,CAAC;AACnC,YAAY,EACV,2BAA2B,EAAE,gCAAgC,EAAE,gCAAgC,EAAE,4BAA4B,GAC9H,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,oBAAoB,EAAE,KAAK,wBAAwB,EAAE,KAAK,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AACxH,OAAO,EAAE,+BAA+B,EAAE,KAAK,4BAA4B,EAAE,MAAM,2BAA2B,CAAC;AAE/G,OAAO,EAAE,4BAA4B,EAAE,KAAK,sBAAsB,EAAE,KAAK,uBAAuB,EAAE,MAAM,mBAAmB,CAAC"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * @file Public barrel for `@jini-ai/agent-plugins/admin-surfaces`: plugin-owned admin surfaces
3
+ * (sandboxed iframes) and the host-mediated action protocol. See `./README.md`.
4
+ *
5
+ * Explicit on purpose: only what a host composes is public. The parsers, checkers and message
6
+ * constants behind these entry points stay internal, so they can change without a host noticing.
7
+ */
8
+ export { adminSurfaceInitMessage, adminSurfaceActionResponse, } from './protocol.js';
9
+ export { readAdminSurfaceTheme, adminSurfaceThemeMessage, ADMIN_SURFACE_THEME_TOKENS, } from './theme.js';
10
+ export { parseAdminSurfacesFile } from './descriptor.js';
11
+ export { adminSurfaceFrameAttributes, createAdminSurfaceMount, createAdminSurfaceBootstrap, adminSurfaceBootstrapHeaders } from './sandbox.js';
12
+ export { validateAdminSurfaceMessage, readAdminSurfaceResize, ADMIN_SURFACE_MIN_HEIGHT, ADMIN_SURFACE_MAX_HEIGHT, } from './host-validator.js';
13
+ // AdminSurfaceActionError stays public: a host's OWN handlers throw it to send a code the surface can show.
14
+ export { createAdminSurfaceActionDispatcher, AdminSurfaceActionError } from './action-dispatcher.js';
15
+ export { defineAdminSurfaceContribution, readAdminSurfaceFile } from './contribution.js';
16
+ export { defineAdminSurfaceHandlerContribution, createAdminSurfaceHandlerHost, } from './surface-handlers.js';
17
+ export { ADMIN_SURFACE_ACTION_INTENTS, ADMIN_SURFACE_STATE_LIMITS, } from './surface-capabilities.js';
18
+ export { openAdminSurfaceLink } from './external-links.js';
19
+ export { createAdminSurfaceCallbackInbox } from './callback-field-inbox.js';
20
+ export { buildAdminSurfaceActionTools } from './action-tools.js';
21
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/admin-surfaces/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EACL,uBAAuB,EAAE,0BAA0B,GAGpD,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,qBAAqB,EAAE,wBAAwB,EAAE,0BAA0B,GAE5E,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,sBAAsB,EAAuF,MAAM,iBAAiB,CAAC;AAC9I,OAAO,EAAE,2BAA2B,EAAE,uBAAuB,EAAE,2BAA2B,EAAE,4BAA4B,EAAE,MAAM,cAAc,CAAC;AAC/I,OAAO,EACL,2BAA2B,EAAE,sBAAsB,EAAE,wBAAwB,EAAE,wBAAwB,GAExG,MAAM,qBAAqB,CAAC;AAC7B,4GAA4G;AAC5G,OAAO,EAAE,kCAAkC,EAAE,uBAAuB,EAAkC,MAAM,wBAAwB,CAAC;AACrI,OAAO,EAAE,8BAA8B,EAAE,oBAAoB,EAA2B,MAAM,mBAAmB,CAAC;AAClH,OAAO,EACL,qCAAqC,EAAE,6BAA6B,GAGrE,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EACL,4BAA4B,EAAE,0BAA0B,GAIzD,MAAM,2BAA2B,CAAC;AAInC,OAAO,EAAE,oBAAoB,EAA+D,MAAM,qBAAqB,CAAC;AACxH,OAAO,EAAE,+BAA+B,EAAqC,MAAM,2BAA2B,CAAC;AAE/G,OAAO,EAAE,4BAA4B,EAA6D,MAAM,mBAAmB,CAAC"}