@agent-native/core 0.206.0-nightly-20261009153146 → 0.206.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 (47) hide show
  1. package/dist/action.d.ts +7 -1
  2. package/dist/client/agent-chat/index.d.ts +1 -1
  3. package/dist/client/agent-chat/index.js +1 -1
  4. package/dist/client/embed-auth.d.ts +2 -0
  5. package/dist/client/embed-auth.js +160 -12
  6. package/dist/client/host/index.d.ts +1 -1
  7. package/dist/client/host/index.js +1 -1
  8. package/dist/client/mcp-app-host.d.ts +1 -0
  9. package/dist/client/mcp-app-host.js +4 -1
  10. package/dist/collab/routes.d.ts +1 -1
  11. package/dist/file-upload/actions/upload-image.d.ts +2 -2
  12. package/dist/mcp/build-server.d.ts +15 -0
  13. package/dist/mcp/build-server.js +307 -91
  14. package/dist/mcp/connect-route.js +1 -0
  15. package/dist/mcp/embed-app.js +291 -31
  16. package/dist/mcp/oauth-route.js +3 -0
  17. package/dist/mcp/oauth-store.d.ts +2 -1
  18. package/dist/mcp/oauth-store.js +5 -6
  19. package/dist/mcp/oauth-token.d.ts +5 -0
  20. package/dist/mcp/oauth-token.js +17 -0
  21. package/dist/mcp/screen-memory-stdio.d.ts +7 -7
  22. package/dist/mcp/server.d.ts +2 -2
  23. package/dist/mcp/server.js +2 -2
  24. package/dist/observability/routes.d.ts +5 -5
  25. package/dist/org/handlers.d.ts +1 -1
  26. package/dist/org/workspace-app-access-request.d.ts +8 -0
  27. package/dist/org/workspace-app-access-request.js +20 -0
  28. package/dist/provider-api/actions/custom-provider-registration.d.ts +4 -4
  29. package/dist/resources/handlers.d.ts +1 -1
  30. package/dist/secrets/routes.d.ts +11 -11
  31. package/dist/server/action-routes.d.ts +2 -0
  32. package/dist/server/action-routes.js +187 -31
  33. package/dist/server/agent-chat/mcp-options.d.ts +3 -1
  34. package/dist/server/agent-chat-plugin.js +26 -1
  35. package/dist/server/agent-engine-ollama-models-route.d.ts +2 -2
  36. package/dist/server/auth.js +11 -20
  37. package/dist/server/embed-route.js +5 -3
  38. package/dist/server/embed-session.d.ts +30 -1
  39. package/dist/server/embed-session.js +376 -30
  40. package/dist/server/realtime-token.d.ts +1 -1
  41. package/dist/server/request-context.d.ts +2 -0
  42. package/dist/server/request-context.js +25 -1
  43. package/dist/shared/embed-auth.d.ts +74 -0
  44. package/dist/shared/embed-auth.js +379 -10
  45. package/dist/sharing/actions/list-resource-shares.d.ts +1 -1
  46. package/dist/triggers/actions/manage-automation.d.ts +3 -3
  47. package/package.json +4 -4
@@ -6,14 +6,28 @@ export declare const MCP_APP_CHAT_BRIDGE_QUERY_PARAM = "__an_mcp_chat_bridge";
6
6
  export declare const MCP_DIRECTORY_WIDGET_QUERY_PARAM = "__an_mcp_directory_widget";
7
7
  export declare const EMBED_SESSION_COOKIE = "an_embed_session";
8
8
  export declare const EMBED_TARGET_HEADER = "x-agent-native-embed-target";
9
+ export declare const MCP_DIRECTORY_WIDGET_SESSION_EXPIRED_HEADER = "x-agent-native-widget-session-expired";
9
10
  export declare const MCP_DIRECTORY_WIDGET_READ_CAPABILITY_PREFIX = "capability:mcp-directory-widget-read:";
11
+ export declare const MCP_DIRECTORY_WIDGET_WRITE_CAPABILITY_PREFIX = "capability:mcp-directory-widget-write:";
10
12
  export declare const MCP_DIRECTORY_WIDGET_READ_CAPABILITY_MAX_LENGTH = 2048;
13
+ export declare const MCP_DIRECTORY_WIDGET_WRITE_CAPABILITY_MAX_LENGTH = 4096;
14
+ export declare const MCP_DIRECTORY_WIDGET_WRITE_CAPABILITY_MAX_AGE_MS: number;
11
15
  export interface McpDirectoryWidgetReadCapabilityInput {
12
16
  appId: string;
13
17
  resourceUri: string;
14
18
  resourceIds: Record<string, string>;
15
19
  actionArguments: Record<string, Record<string, McpDirectoryWidgetReadArgument>>;
16
20
  }
21
+ export interface McpDirectoryWidgetWriteCapabilityInput {
22
+ appId: string;
23
+ resourceUri: string;
24
+ resourceIds: Record<string, string>;
25
+ userEmail: string;
26
+ orgId?: string;
27
+ expiresAtMs: number;
28
+ readActionArguments: Record<string, Record<string, McpDirectoryWidgetReadArgument>>;
29
+ writeActionArguments: Record<string, Record<string, McpDirectoryWidgetReadArgument>>;
30
+ }
17
31
  export type McpDirectoryWidgetReadArgument = string | {
18
32
  type: "integerRange";
19
33
  min: number;
@@ -22,21 +36,81 @@ export type McpDirectoryWidgetReadArgument = string | {
22
36
  /** Dynamic input validated against the server action schema after resource binding. */
23
37
  | {
24
38
  type: "actionSchema";
39
+ }
40
+ /** Dynamic input whose artifact relationship is checked by the action. */
41
+ | {
42
+ type: "actionSchemaResourceBound";
43
+ resourceKey: string;
25
44
  };
26
45
  export declare function createMcpDirectoryWidgetReadCapability(input: McpDirectoryWidgetReadCapabilityInput): string | undefined;
46
+ export declare function createMcpDirectoryWidgetWriteCapability(input: McpDirectoryWidgetWriteCapabilityInput): string | undefined;
47
+ export declare function renewMcpDirectoryWidgetCapabilityScope(scope: string | undefined, input: {
48
+ appId: string;
49
+ resourceUri: string;
50
+ userEmail: string;
51
+ orgId?: string | null;
52
+ expiresAtMs: number;
53
+ readAllowed: boolean;
54
+ writeAllowed: boolean;
55
+ }): string | undefined;
56
+ export declare function canRenewMcpDirectoryWidgetCapabilityScope(previousScope: string, renewedScope: string, identity: {
57
+ userEmail: string;
58
+ orgId?: string | null;
59
+ }): boolean;
27
60
  export declare function isMcpDirectoryWidgetReadCapabilityScope(scope: string | undefined): boolean;
61
+ export declare function isMcpDirectoryWidgetWriteCapabilityScope(scope: string | undefined): boolean;
62
+ export declare function isMcpDirectoryWidgetCapabilityScope(scope: string | undefined): boolean;
63
+ export declare function matchesMcpDirectoryWidgetWriteCapability(scope: string | undefined, input: {
64
+ appId: string;
65
+ resourceUri: string;
66
+ userEmail: string;
67
+ orgId?: string | null;
68
+ }): boolean;
69
+ export declare function isExpiredMcpDirectoryWidgetWriteCapability(scope: string | undefined, input: {
70
+ appId: string;
71
+ resourceUri: string;
72
+ userEmail: string;
73
+ orgId?: string | null;
74
+ }): boolean;
75
+ export declare function getMcpDirectoryWidgetWriteCapabilityGrant(scope: string | undefined, input: {
76
+ appId: string;
77
+ resourceUri: string;
78
+ userEmail: string;
79
+ orgId?: string | null;
80
+ }): {
81
+ resourceIds: Record<string, string>;
82
+ actionNames: string[];
83
+ } | undefined;
84
+ export declare function getMcpDirectoryWidgetWriteCapabilityExpiresAt(scope: string | undefined): number | undefined;
85
+ export declare function matchesMcpDirectoryWidgetReadCapabilityResource(scope: string | undefined, input: {
86
+ appId: string;
87
+ resourceUri: string;
88
+ }): boolean;
28
89
  export declare function normalizeMcpDirectoryWidgetReadActionArguments(scope: string | undefined, input: {
29
90
  actionName: string;
30
91
  appId: string | undefined;
31
92
  resourceUri: string | undefined;
32
93
  args?: Record<string, unknown>;
94
+ userEmail?: string;
95
+ orgId?: string | null;
33
96
  allowedArgumentNames?: readonly string[];
34
97
  requireArgumentMatch?: boolean;
35
98
  }): Record<string, unknown> | undefined;
99
+ export declare function normalizeMcpDirectoryWidgetWriteActionArguments(scope: string | undefined, input: {
100
+ actionName: string;
101
+ appId: string | undefined;
102
+ resourceUri: string | undefined;
103
+ userEmail: string | undefined;
104
+ orgId?: string | null;
105
+ args?: Record<string, unknown>;
106
+ allowedArgumentNames?: readonly string[];
107
+ }): Record<string, unknown> | undefined;
36
108
  export declare function allowsMcpDirectoryWidgetReadAction(scope: string | undefined, input: {
37
109
  actionName: string;
38
110
  appId: string | undefined;
39
111
  resourceUri: string | undefined;
112
+ userEmail?: string;
113
+ orgId?: string | null;
40
114
  args?: Record<string, unknown>;
41
115
  allowedArgumentNames?: readonly string[];
42
116
  requireArgumentMatch?: boolean;
@@ -6,8 +6,12 @@ export const MCP_APP_CHAT_BRIDGE_QUERY_PARAM = "__an_mcp_chat_bridge";
6
6
  export const MCP_DIRECTORY_WIDGET_QUERY_PARAM = "__an_mcp_directory_widget";
7
7
  export const EMBED_SESSION_COOKIE = "an_embed_session";
8
8
  export const EMBED_TARGET_HEADER = "x-agent-native-embed-target";
9
+ export const MCP_DIRECTORY_WIDGET_SESSION_EXPIRED_HEADER = "x-agent-native-widget-session-expired";
9
10
  export const MCP_DIRECTORY_WIDGET_READ_CAPABILITY_PREFIX = "capability:mcp-directory-widget-read:";
11
+ export const MCP_DIRECTORY_WIDGET_WRITE_CAPABILITY_PREFIX = "capability:mcp-directory-widget-write:";
10
12
  export const MCP_DIRECTORY_WIDGET_READ_CAPABILITY_MAX_LENGTH = 2048;
13
+ export const MCP_DIRECTORY_WIDGET_WRITE_CAPABILITY_MAX_LENGTH = 4096;
14
+ export const MCP_DIRECTORY_WIDGET_WRITE_CAPABILITY_MAX_AGE_MS = 15 * 60 * 1000;
11
15
  const MCP_DIRECTORY_WIDGET_INTEGER_ARGUMENT_MAX = 5_000;
12
16
  const MCP_DIRECTORY_ACTION_NAME = /^[A-Za-z0-9_.-]{1,128}$/;
13
17
  const MCP_DIRECTORY_SCOPE_KEY = /^[A-Za-z0-9_.-]{1,128}$/;
@@ -25,7 +29,7 @@ function isStringRecord(value, { minEntries = 1, maxEntries = 16 } = {}) {
25
29
  item.length <= 256 &&
26
30
  !CONTROL_CHARS.test(item)));
27
31
  }
28
- function isWidgetReadArgument(value) {
32
+ function isWidgetReadArgument(value, allowResourceBound = false) {
29
33
  if (typeof value === "string") {
30
34
  return (value.length > 0 && value.length <= 256 && !CONTROL_CHARS.test(value));
31
35
  }
@@ -36,6 +40,12 @@ function isWidgetReadArgument(value) {
36
40
  if (range.type === "actionSchema") {
37
41
  return Object.keys(range).length === 1;
38
42
  }
43
+ if (range.type === "actionSchemaResourceBound") {
44
+ return (allowResourceBound &&
45
+ Object.keys(range).length === 2 &&
46
+ typeof range.resourceKey === "string" &&
47
+ MCP_DIRECTORY_SCOPE_KEY.test(range.resourceKey));
48
+ }
39
49
  return (range.type === "integerRange" &&
40
50
  Object.keys(range).length === 3 &&
41
51
  Number.isSafeInteger(range.min) &&
@@ -44,14 +54,15 @@ function isWidgetReadArgument(value) {
44
54
  range.max >= range.min &&
45
55
  range.max <= MCP_DIRECTORY_WIDGET_INTEGER_ARGUMENT_MAX);
46
56
  }
47
- function isWidgetReadArgumentRecord(value, { minEntries = 1, maxEntries = 16 } = {}) {
57
+ function isWidgetReadArgumentRecord(value, { minEntries = 1, maxEntries = 16, allowResourceBound = false, } = {}) {
48
58
  if (!value || typeof value !== "object" || Array.isArray(value)) {
49
59
  return false;
50
60
  }
51
61
  const entries = Object.entries(value);
52
62
  return (entries.length >= minEntries &&
53
63
  entries.length <= maxEntries &&
54
- entries.every(([key, item]) => MCP_DIRECTORY_SCOPE_KEY.test(key) && isWidgetReadArgument(item)));
64
+ entries.every(([key, item]) => MCP_DIRECTORY_SCOPE_KEY.test(key) &&
65
+ isWidgetReadArgument(item, allowResourceBound)));
55
66
  }
56
67
  function isWidgetReadCapability(value) {
57
68
  if (!value || typeof value !== "object" || Array.isArray(value)) {
@@ -109,6 +120,68 @@ function decodeMcpDirectoryWidgetReadCapability(scope) {
109
120
  ? { ok: true, capability: value }
110
121
  : { ok: false, reason: "invalid-capability" };
111
122
  }
123
+ function decodeMcpDirectoryWidgetWriteCapability(scope) {
124
+ if (!scope.startsWith(MCP_DIRECTORY_WIDGET_WRITE_CAPABILITY_PREFIX) ||
125
+ scope.length > MCP_DIRECTORY_WIDGET_WRITE_CAPABILITY_MAX_LENGTH) {
126
+ return undefined;
127
+ }
128
+ try {
129
+ const value = JSON.parse(decodeURIComponent(scope.slice(MCP_DIRECTORY_WIDGET_WRITE_CAPABILITY_PREFIX.length)));
130
+ if (value.version !== 1 ||
131
+ typeof value.appId !== "string" ||
132
+ !MCP_DIRECTORY_SCOPE_KEY.test(value.appId) ||
133
+ typeof value.resourceUri !== "string" ||
134
+ !value.resourceUri.startsWith("ui://") ||
135
+ value.resourceUri.length > 512 ||
136
+ CONTROL_CHARS.test(value.resourceUri) ||
137
+ !isStringRecord(value.resourceIds) ||
138
+ typeof value.userEmail !== "string" ||
139
+ value.userEmail.length > 320 ||
140
+ CONTROL_CHARS.test(value.userEmail) ||
141
+ (value.orgId !== undefined &&
142
+ (typeof value.orgId !== "string" ||
143
+ value.orgId.length > 256 ||
144
+ CONTROL_CHARS.test(value.orgId))) ||
145
+ !Number.isSafeInteger(value.expiresAtMs)) {
146
+ return undefined;
147
+ }
148
+ const readActionArguments = value.readActionArguments;
149
+ const writeActionArguments = value.writeActionArguments;
150
+ if (!isWidgetActionArgumentMap(readActionArguments, { minActions: 0 }) ||
151
+ !isWidgetActionArgumentMap(writeActionArguments, {
152
+ maxArguments: 32,
153
+ allowResourceBound: true,
154
+ }) ||
155
+ Object.keys(writeActionArguments).some((actionName) => {
156
+ const args = writeActionArguments[actionName];
157
+ return !Object.values(args).some((argument) => typeof argument === "string"
158
+ ? Object.values(value.resourceIds).includes(argument)
159
+ : argument.type === "actionSchemaResourceBound" &&
160
+ Object.hasOwn(value.resourceIds, argument.resourceKey));
161
+ })) {
162
+ return undefined;
163
+ }
164
+ return value;
165
+ }
166
+ catch {
167
+ // coercion-ok: malformed caller scope remains an absent, denied capability.
168
+ return undefined;
169
+ }
170
+ }
171
+ function isWidgetActionArgumentMap(value, { minActions = 1, maxArguments = 16, allowResourceBound = false, } = {}) {
172
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
173
+ return false;
174
+ }
175
+ const actions = Object.entries(value);
176
+ return (actions.length >= minActions &&
177
+ actions.length <= 32 &&
178
+ actions.every(([actionName, args]) => MCP_DIRECTORY_ACTION_NAME.test(actionName) &&
179
+ isWidgetReadArgumentRecord(args, {
180
+ minEntries: 0,
181
+ maxEntries: maxArguments,
182
+ allowResourceBound,
183
+ })));
184
+ }
112
185
  function sortStringRecord(value) {
113
186
  return Object.fromEntries(Object.entries(value).sort(([a], [b]) => a.localeCompare(b)));
114
187
  }
@@ -156,22 +229,253 @@ export function createMcpDirectoryWidgetReadCapability(input) {
156
229
  ? scope
157
230
  : undefined;
158
231
  }
232
+ export function createMcpDirectoryWidgetWriteCapability(input) {
233
+ const now = Date.now();
234
+ if (!input ||
235
+ typeof input.appId !== "string" ||
236
+ !MCP_DIRECTORY_SCOPE_KEY.test(input.appId) ||
237
+ typeof input.resourceUri !== "string" ||
238
+ !input.resourceUri.startsWith("ui://") ||
239
+ input.resourceUri.length > 512 ||
240
+ CONTROL_CHARS.test(input.resourceUri) ||
241
+ !isStringRecord(input.resourceIds) ||
242
+ typeof input.userEmail !== "string" ||
243
+ !input.userEmail.trim() ||
244
+ input.userEmail.length > 320 ||
245
+ CONTROL_CHARS.test(input.userEmail) ||
246
+ (input.orgId !== undefined &&
247
+ (typeof input.orgId !== "string" ||
248
+ !input.orgId.trim() ||
249
+ input.orgId.length > 256 ||
250
+ CONTROL_CHARS.test(input.orgId))) ||
251
+ !Number.isSafeInteger(input.expiresAtMs) ||
252
+ input.expiresAtMs <= now ||
253
+ input.expiresAtMs >
254
+ now + MCP_DIRECTORY_WIDGET_WRITE_CAPABILITY_MAX_AGE_MS ||
255
+ !isWidgetActionArgumentMap(input.readActionArguments, { minActions: 0 }) ||
256
+ !isWidgetActionArgumentMap(input.writeActionArguments, {
257
+ maxArguments: 32,
258
+ allowResourceBound: true,
259
+ }) ||
260
+ Object.values(input.writeActionArguments).some((args) => !Object.values(args).some((argument) => typeof argument === "string"
261
+ ? Object.values(input.resourceIds).includes(argument)
262
+ : argument.type === "actionSchemaResourceBound" &&
263
+ Object.hasOwn(input.resourceIds, argument.resourceKey)))) {
264
+ return undefined;
265
+ }
266
+ const capability = {
267
+ version: 1,
268
+ appId: input.appId,
269
+ resourceUri: input.resourceUri,
270
+ resourceIds: sortStringRecord(input.resourceIds),
271
+ userEmail: input.userEmail.trim().toLowerCase(),
272
+ ...(input.orgId ? { orgId: input.orgId } : {}),
273
+ expiresAtMs: input.expiresAtMs,
274
+ readActionArguments: Object.fromEntries(Object.entries(input.readActionArguments)
275
+ .sort(([a], [b]) => a.localeCompare(b))
276
+ .map(([actionName, args]) => [
277
+ actionName,
278
+ sortWidgetReadArgumentRecord(args),
279
+ ])),
280
+ writeActionArguments: Object.fromEntries(Object.entries(input.writeActionArguments)
281
+ .sort(([a], [b]) => a.localeCompare(b))
282
+ .map(([actionName, args]) => [
283
+ actionName,
284
+ sortWidgetReadArgumentRecord(args),
285
+ ])),
286
+ };
287
+ const scope = MCP_DIRECTORY_WIDGET_WRITE_CAPABILITY_PREFIX +
288
+ encodeURIComponent(JSON.stringify(capability));
289
+ return scope.length <= MCP_DIRECTORY_WIDGET_WRITE_CAPABILITY_MAX_LENGTH
290
+ ? scope
291
+ : undefined;
292
+ }
293
+ export function renewMcpDirectoryWidgetCapabilityScope(scope, input) {
294
+ if (!scope || !input.appId || !input.userEmail || !input.readAllowed) {
295
+ return undefined;
296
+ }
297
+ if (isMcpDirectoryWidgetWriteCapabilityScope(scope)) {
298
+ const capability = decodeMcpDirectoryWidgetWriteCapability(scope);
299
+ if (!capability ||
300
+ capability.appId !== input.appId ||
301
+ capability.userEmail !== input.userEmail.trim().toLowerCase() ||
302
+ capability.orgId !== (input.orgId ?? undefined)) {
303
+ return undefined;
304
+ }
305
+ if (!input.writeAllowed) {
306
+ return createMcpDirectoryWidgetReadCapability({
307
+ appId: capability.appId,
308
+ resourceUri: input.resourceUri,
309
+ resourceIds: capability.resourceIds,
310
+ actionArguments: capability.readActionArguments,
311
+ });
312
+ }
313
+ return createMcpDirectoryWidgetWriteCapability({
314
+ ...capability,
315
+ resourceUri: input.resourceUri,
316
+ expiresAtMs: input.expiresAtMs,
317
+ });
318
+ }
319
+ const decoded = decodeMcpDirectoryWidgetReadCapability(scope);
320
+ return decoded.ok && decoded.capability.appId === input.appId
321
+ ? createMcpDirectoryWidgetReadCapability({
322
+ ...decoded.capability,
323
+ resourceUri: input.resourceUri,
324
+ })
325
+ : undefined;
326
+ }
327
+ function sameWidgetActionArguments(left, right) {
328
+ const normalize = (value) => Object.fromEntries(Object.entries(value)
329
+ .sort(([a], [b]) => a.localeCompare(b))
330
+ .map(([actionName, args]) => [
331
+ actionName,
332
+ Object.fromEntries(Object.entries(args).sort(([a], [b]) => a.localeCompare(b))),
333
+ ]));
334
+ return JSON.stringify(normalize(left)) === JSON.stringify(normalize(right));
335
+ }
336
+ export function canRenewMcpDirectoryWidgetCapabilityScope(previousScope, renewedScope, identity) {
337
+ if (!identity.userEmail.trim())
338
+ return false;
339
+ const previousWrite = isMcpDirectoryWidgetWriteCapabilityScope(previousScope);
340
+ const renewedWrite = isMcpDirectoryWidgetWriteCapabilityScope(renewedScope);
341
+ if (renewedWrite && !previousWrite)
342
+ return false;
343
+ const identityMatches = (capability) => capability.userEmail === identity.userEmail.trim().toLowerCase() &&
344
+ capability.orgId === (identity.orgId ?? undefined);
345
+ if (previousWrite) {
346
+ const previous = decodeMcpDirectoryWidgetWriteCapability(previousScope);
347
+ if (!previous || !identityMatches(previous))
348
+ return false;
349
+ if (renewedWrite) {
350
+ const renewed = decodeMcpDirectoryWidgetWriteCapability(renewedScope);
351
+ return Boolean(renewed &&
352
+ identityMatches(renewed) &&
353
+ renewed.appId === previous.appId &&
354
+ sameWidgetActionArguments(renewed.readActionArguments, previous.readActionArguments) &&
355
+ sameWidgetActionArguments(renewed.writeActionArguments, previous.writeActionArguments) &&
356
+ JSON.stringify(renewed.resourceIds) ===
357
+ JSON.stringify(previous.resourceIds));
358
+ }
359
+ const renewed = decodeMcpDirectoryWidgetReadCapability(renewedScope);
360
+ return Boolean(renewed.ok &&
361
+ renewed.capability.appId === previous.appId &&
362
+ sameWidgetActionArguments(renewed.capability.actionArguments, previous.readActionArguments) &&
363
+ JSON.stringify(renewed.capability.resourceIds) ===
364
+ JSON.stringify(previous.resourceIds));
365
+ }
366
+ const previous = decodeMcpDirectoryWidgetReadCapability(previousScope);
367
+ const renewed = decodeMcpDirectoryWidgetReadCapability(renewedScope);
368
+ return Boolean(!renewedWrite &&
369
+ previous.ok &&
370
+ renewed.ok &&
371
+ renewed.capability.appId === previous.capability.appId &&
372
+ sameWidgetActionArguments(renewed.capability.actionArguments, previous.capability.actionArguments) &&
373
+ JSON.stringify(renewed.capability.resourceIds) ===
374
+ JSON.stringify(previous.capability.resourceIds));
375
+ }
159
376
  export function isMcpDirectoryWidgetReadCapabilityScope(scope) {
160
377
  return (scope?.startsWith(MCP_DIRECTORY_WIDGET_READ_CAPABILITY_PREFIX) === true);
161
378
  }
379
+ export function isMcpDirectoryWidgetWriteCapabilityScope(scope) {
380
+ return (scope?.startsWith(MCP_DIRECTORY_WIDGET_WRITE_CAPABILITY_PREFIX) === true);
381
+ }
382
+ export function isMcpDirectoryWidgetCapabilityScope(scope) {
383
+ return (isMcpDirectoryWidgetReadCapabilityScope(scope) ||
384
+ isMcpDirectoryWidgetWriteCapabilityScope(scope));
385
+ }
386
+ export function matchesMcpDirectoryWidgetWriteCapability(scope, input) {
387
+ if (!scope || !isMcpDirectoryWidgetWriteCapabilityScope(scope)) {
388
+ return false;
389
+ }
390
+ const capability = decodeMcpDirectoryWidgetWriteCapability(scope);
391
+ return (capability !== undefined &&
392
+ capability.expiresAtMs > Date.now() &&
393
+ capability.appId === input.appId &&
394
+ capability.resourceUri === input.resourceUri &&
395
+ capability.userEmail === input.userEmail.trim().toLowerCase() &&
396
+ capability.orgId === (input.orgId ?? undefined));
397
+ }
398
+ export function isExpiredMcpDirectoryWidgetWriteCapability(scope, input) {
399
+ if (!scope || !isMcpDirectoryWidgetWriteCapabilityScope(scope)) {
400
+ return false;
401
+ }
402
+ const capability = decodeMcpDirectoryWidgetWriteCapability(scope);
403
+ return (capability !== undefined &&
404
+ capability.expiresAtMs <= Date.now() &&
405
+ capability.appId === input.appId &&
406
+ capability.resourceUri === input.resourceUri &&
407
+ capability.userEmail === input.userEmail.trim().toLowerCase() &&
408
+ capability.orgId === (input.orgId ?? undefined));
409
+ }
410
+ export function getMcpDirectoryWidgetWriteCapabilityGrant(scope, input) {
411
+ if (!matchesMcpDirectoryWidgetWriteCapability(scope, input) || !scope) {
412
+ return undefined;
413
+ }
414
+ const capability = decodeMcpDirectoryWidgetWriteCapability(scope);
415
+ return capability
416
+ ? {
417
+ resourceIds: { ...capability.resourceIds },
418
+ actionNames: Object.keys(capability.writeActionArguments),
419
+ }
420
+ : undefined;
421
+ }
422
+ export function getMcpDirectoryWidgetWriteCapabilityExpiresAt(scope) {
423
+ if (!scope || !isMcpDirectoryWidgetWriteCapabilityScope(scope)) {
424
+ return undefined;
425
+ }
426
+ return decodeMcpDirectoryWidgetWriteCapability(scope)?.expiresAtMs;
427
+ }
428
+ export function matchesMcpDirectoryWidgetReadCapabilityResource(scope, input) {
429
+ if (!scope || !isMcpDirectoryWidgetReadCapabilityScope(scope))
430
+ return false;
431
+ const decoded = decodeMcpDirectoryWidgetReadCapability(scope);
432
+ return (decoded.ok &&
433
+ decoded.capability.appId === input.appId &&
434
+ decoded.capability.resourceUri === input.resourceUri);
435
+ }
436
+ function widgetReadActionArgumentsForScope(scope) {
437
+ if (isMcpDirectoryWidgetWriteCapabilityScope(scope)) {
438
+ const capability = decodeMcpDirectoryWidgetWriteCapability(scope);
439
+ return capability && capability.expiresAtMs > Date.now()
440
+ ? capability.readActionArguments
441
+ : undefined;
442
+ }
443
+ const decoded = decodeMcpDirectoryWidgetReadCapability(scope);
444
+ return decoded.ok ? decoded.capability.actionArguments : undefined;
445
+ }
162
446
  export function normalizeMcpDirectoryWidgetReadActionArguments(scope, input) {
163
447
  if (!scope || !input.appId || !input.resourceUri)
164
448
  return undefined;
165
- const decoded = decodeMcpDirectoryWidgetReadCapability(scope);
166
- if (!decoded.ok)
449
+ const actionArguments = widgetReadActionArgumentsForScope(scope);
450
+ if (!actionArguments)
167
451
  return undefined;
168
- const capability = decoded.capability;
169
- if (!capability ||
170
- capability.appId !== input.appId ||
171
- capability.resourceUri !== input.resourceUri) {
452
+ let capabilityAppId;
453
+ let capabilityResourceUri;
454
+ let capabilityUserEmail;
455
+ let capabilityOrgId;
456
+ if (isMcpDirectoryWidgetWriteCapabilityScope(scope)) {
457
+ const capability = decodeMcpDirectoryWidgetWriteCapability(scope);
458
+ capabilityAppId = capability?.appId;
459
+ capabilityResourceUri = capability?.resourceUri;
460
+ capabilityUserEmail = capability?.userEmail;
461
+ capabilityOrgId = capability?.orgId;
462
+ }
463
+ else {
464
+ const decoded = decodeMcpDirectoryWidgetReadCapability(scope);
465
+ capabilityAppId = decoded.ok ? decoded.capability.appId : undefined;
466
+ capabilityResourceUri = decoded.ok
467
+ ? decoded.capability.resourceUri
468
+ : undefined;
469
+ }
470
+ if (capabilityAppId !== input.appId ||
471
+ capabilityResourceUri !== input.resourceUri ||
472
+ (capabilityUserEmail &&
473
+ capabilityUserEmail !== input.userEmail?.trim().toLowerCase()) ||
474
+ (isMcpDirectoryWidgetWriteCapabilityScope(scope) &&
475
+ capabilityOrgId !== (input.orgId ?? undefined))) {
172
476
  return undefined;
173
477
  }
174
- const expectedArgs = capability.actionArguments[input.actionName];
478
+ const expectedArgs = actionArguments[input.actionName];
175
479
  if (!expectedArgs)
176
480
  return undefined;
177
481
  const allowedNames = [...(input.allowedArgumentNames ?? [])].sort();
@@ -205,6 +509,71 @@ export function normalizeMcpDirectoryWidgetReadActionArguments(scope, input) {
205
509
  normalizedArgs.push([name, value]);
206
510
  continue;
207
511
  }
512
+ if (expected.type === "actionSchemaResourceBound")
513
+ return undefined;
514
+ const number = typeof value === "number"
515
+ ? value
516
+ : typeof value === "string" && /^(0|[1-9]\d*)$/.test(value)
517
+ ? Number(value)
518
+ : Number.NaN;
519
+ if (!Number.isSafeInteger(number) ||
520
+ number < expected.min ||
521
+ number > expected.max) {
522
+ return undefined;
523
+ }
524
+ normalizedArgs.push([name, number]);
525
+ }
526
+ return Object.fromEntries(normalizedArgs);
527
+ }
528
+ export function normalizeMcpDirectoryWidgetWriteActionArguments(scope, input) {
529
+ if (!scope ||
530
+ !isMcpDirectoryWidgetWriteCapabilityScope(scope) ||
531
+ !input.appId ||
532
+ !input.resourceUri ||
533
+ !input.userEmail) {
534
+ return undefined;
535
+ }
536
+ const capability = decodeMcpDirectoryWidgetWriteCapability(scope);
537
+ if (!capability ||
538
+ capability.expiresAtMs <= Date.now() ||
539
+ capability.appId !== input.appId ||
540
+ capability.resourceUri !== input.resourceUri ||
541
+ capability.userEmail !== input.userEmail.trim().toLowerCase() ||
542
+ capability.orgId !== (input.orgId ?? undefined)) {
543
+ return undefined;
544
+ }
545
+ const expectedArgs = capability.writeActionArguments[input.actionName];
546
+ if (!expectedArgs)
547
+ return undefined;
548
+ const allowedNames = [...(input.allowedArgumentNames ?? [])].sort();
549
+ const expectedNames = Object.keys(expectedArgs).sort();
550
+ if (allowedNames.length !== expectedNames.length ||
551
+ allowedNames.some((name, index) => name !== expectedNames[index])) {
552
+ return undefined;
553
+ }
554
+ const suppliedArgs = Object.entries(input.args ?? {});
555
+ const includesResourceBinding = suppliedArgs.some(([name, value]) => typeof expectedArgs[name] === "string" && expectedArgs[name] === value) ||
556
+ Object.values(expectedArgs).some((expected) => typeof expected !== "string" &&
557
+ expected.type === "actionSchemaResourceBound" &&
558
+ Object.hasOwn(capability.resourceIds, expected.resourceKey));
559
+ if (!includesResourceBinding)
560
+ return undefined;
561
+ const normalizedArgs = [];
562
+ for (const [name, value] of suppliedArgs) {
563
+ if (!Object.hasOwn(expectedArgs, name))
564
+ return undefined;
565
+ const expected = expectedArgs[name];
566
+ if (typeof expected === "string") {
567
+ if (expected !== value)
568
+ return undefined;
569
+ normalizedArgs.push([name, value]);
570
+ continue;
571
+ }
572
+ if (expected.type === "actionSchema" ||
573
+ expected.type === "actionSchemaResourceBound") {
574
+ normalizedArgs.push([name, value]);
575
+ continue;
576
+ }
208
577
  const number = typeof value === "number"
209
578
  ? value
210
579
  : typeof value === "string" && /^(0|[1-9]\d*)$/.test(value)
@@ -2,6 +2,7 @@ declare const _default: import("../../action.js").ActionDefinition<{
2
2
  resourceType: string;
3
3
  resourceId: string;
4
4
  }, {
5
+ role?: undefined;
5
6
  ownerEmail: any;
6
7
  visibility: any;
7
8
  shares: any[];
@@ -11,7 +12,6 @@ declare const _default: import("../../action.js").ActionDefinition<{
11
12
  supportsGroupShares?: boolean;
12
13
  };
13
14
  orgId?: undefined;
14
- role?: undefined;
15
15
  agentReadable?: undefined;
16
16
  } | {
17
17
  ownerEmail: string;
@@ -14,6 +14,7 @@ declare const _default: import("../../action.js").ActionDefinition<{
14
14
  executionCwd?: string;
15
15
  }, {
16
16
  deleted?: undefined;
17
+ enabled?: undefined;
17
18
  created: boolean;
18
19
  name: string;
19
20
  scope: "organization" | "personal";
@@ -24,25 +25,24 @@ declare const _default: import("../../action.js").ActionDefinition<{
24
25
  reasoningEffort: "auto" | "high" | "low" | "max" | "medium" | "minimal" | "none" | "xhigh";
25
26
  webhookPath: string;
26
27
  nextRun: string;
27
- enabled?: undefined;
28
28
  executionHostId?: undefined;
29
29
  executionEngine?: undefined;
30
30
  executionCwd?: undefined;
31
31
  } | {
32
+ enabled?: undefined;
33
+ nextRun?: undefined;
32
34
  created?: undefined;
33
35
  scope?: undefined;
34
36
  triggerType?: undefined;
35
37
  event?: undefined;
36
38
  deleted: boolean;
37
39
  name: string;
38
- enabled?: undefined;
39
40
  schedule?: undefined;
40
41
  timezone?: undefined;
41
42
  reasoningEffort?: undefined;
42
43
  executionHostId?: undefined;
43
44
  executionEngine?: undefined;
44
45
  executionCwd?: undefined;
45
- nextRun?: undefined;
46
46
  webhookPath?: undefined;
47
47
  } | {
48
48
  deleted?: undefined;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agent-native/core",
3
- "version": "0.206.0-nightly-20261009153146",
3
+ "version": "0.206.0",
4
4
  "description": "The agentic application framework for building autonomous agents with intuitive UIs",
5
5
  "homepage": "https://github.com/BuilderIO/agent-native#readme",
6
6
  "bugs": {
@@ -688,8 +688,8 @@
688
688
  "yaml": "^2.9.0",
689
689
  "yjs": "^13.6.33",
690
690
  "zod": "^4.3.6",
691
- "@agent-native/agentkit": "^0.206.0-nightly-20261009153146",
692
- "@agent-native/recap-cli": "^0.5.68-nightly-20261009153146"
691
+ "@agent-native/agentkit": "^0.206.0",
692
+ "@agent-native/recap-cli": "^0.5.68"
693
693
  },
694
694
  "devDependencies": {
695
695
  "@ai-sdk/anthropic": "^3.0.71",
@@ -759,7 +759,7 @@
759
759
  "xlsx": "^0.18.5"
760
760
  },
761
761
  "peerDependencies": {
762
- "@agent-native/core-corpus": "0.206.0-nightly-20261009153146",
762
+ "@agent-native/core-corpus": ">=0.196.0",
763
763
  "@ai-sdk/anthropic": ">=3",
764
764
  "@ai-sdk/cohere": ">=3",
765
765
  "@ai-sdk/google": ">=3",