@agent-native/core 0.124.6 → 0.126.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 (43) hide show
  1. package/corpus/README.md +1 -1
  2. package/corpus/core/CHANGELOG.md +14 -0
  3. package/corpus/core/package.json +1 -1
  4. package/corpus/core/src/server/email-template.ts +37 -1
  5. package/corpus/core/src/server/email.ts +40 -4
  6. package/corpus/core/src/sharing/actions/share-resource.ts +65 -2
  7. package/corpus/core/src/sharing/registry.ts +49 -0
  8. package/corpus/templates/assets/actions/edit-image.ts +31 -18
  9. package/corpus/templates/assets/actions/refine-image.ts +43 -29
  10. package/corpus/templates/assets/actions/restyle-image.ts +30 -19
  11. package/corpus/templates/assets/actions/variant-slots.ts +26 -0
  12. package/corpus/templates/assets/app/components/generation/GenerationResults.tsx +85 -17
  13. package/corpus/templates/clips/changelog/2026-07-27-organization-brand-logos-now-upload-to-configured-file-stora.md +6 -0
  14. package/corpus/templates/clips/changelog/2026-07-27-share-notification-emails-now-include-a-clickable-recording-.md +6 -0
  15. package/corpus/templates/clips/server/db/index.ts +45 -0
  16. package/corpus/templates/clips/server/lib/share-email-hero.ts +105 -0
  17. package/corpus/templates/clips/server/routes/api/media/index.post.ts +19 -31
  18. package/corpus/templates/design/.generated/bridge/editor-chrome.generated.ts +100 -12
  19. package/corpus/templates/design/app/components/design/DesignCanvas.tsx +17 -0
  20. package/corpus/templates/design/app/components/design/bridge/editor-chrome.bridge.ts +169 -22
  21. package/dist/collab/routes.d.ts +2 -2
  22. package/dist/observability/routes.d.ts +3 -3
  23. package/dist/provider-api/actions/provider-api.d.ts +8 -8
  24. package/dist/server/email-template.d.ts +12 -0
  25. package/dist/server/email-template.d.ts.map +1 -1
  26. package/dist/server/email-template.js +24 -1
  27. package/dist/server/email-template.js.map +1 -1
  28. package/dist/server/email.d.ts +7 -0
  29. package/dist/server/email.d.ts.map +1 -1
  30. package/dist/server/email.js +31 -6
  31. package/dist/server/email.js.map +1 -1
  32. package/dist/server/transcribe-voice.d.ts +1 -1
  33. package/dist/sharing/actions/share-resource.d.ts.map +1 -1
  34. package/dist/sharing/actions/share-resource.js +57 -2
  35. package/dist/sharing/actions/share-resource.js.map +1 -1
  36. package/dist/sharing/registry.d.ts +46 -0
  37. package/dist/sharing/registry.d.ts.map +1 -1
  38. package/dist/sharing/registry.js.map +1 -1
  39. package/package.json +1 -1
  40. package/src/server/email-template.ts +37 -1
  41. package/src/server/email.ts +40 -4
  42. package/src/sharing/actions/share-resource.ts +65 -2
  43. package/src/sharing/registry.ts +49 -0
@@ -8,6 +8,7 @@ import { renderEmail, emailStrong } from "../../server/email-template.js";
8
8
  import { sendEmail, isEmailConfigured } from "../../server/email.js";
9
9
  import { invalidateCollabAccessCache } from "../../server/poll.js";
10
10
  import { getRequestUserEmail } from "../../server/request-context.js";
11
+ import { getUserProfile } from "../../user-profile/store.js";
11
12
  import { assertAccess, ForbiddenError } from "../access.js";
12
13
  import { requireShareableResource } from "../registry.js";
13
14
  import {
@@ -297,19 +298,81 @@ export default defineAction({
297
298
  );
298
299
  const appName =
299
300
  process.env.APP_NAME || process.env.VITE_APP_NAME || "Agent Native";
301
+ let brandLogoUrl: string | undefined;
302
+ if (reg.getLogoUrl) {
303
+ try {
304
+ brandLogoUrl = (await reg.getLogoUrl(resource)) ?? undefined;
305
+ } catch (err) {
306
+ console.error(
307
+ "[share-resource] brand logo resolver failed; using default logo:",
308
+ err,
309
+ );
310
+ }
311
+ }
312
+ let brandName = appName;
313
+ if (reg.getBrandName) {
314
+ try {
315
+ brandName = (await reg.getBrandName(resource))?.trim() || appName;
316
+ } catch (err) {
317
+ console.error(
318
+ "[share-resource] brand name resolver failed; using app name:",
319
+ err,
320
+ );
321
+ }
322
+ }
323
+ let fromName: string | undefined;
324
+ let replyTo: string | undefined;
325
+ if (reg.getSender) {
326
+ try {
327
+ const sender = await reg.getSender(resource, {
328
+ sender: await getUserProfile(actor),
329
+ });
330
+ fromName = sender?.fromName?.trim() || undefined;
331
+ replyTo = sender?.replyTo?.trim() || undefined;
332
+ } catch (err) {
333
+ console.error(
334
+ "[share-resource] sender resolver failed; using default sender:",
335
+ err,
336
+ );
337
+ }
338
+ }
339
+ let heroHtml: string | undefined;
340
+ if (reg.getHeroHtml) {
341
+ try {
342
+ heroHtml =
343
+ (await reg.getHeroHtml(resource, {
344
+ href: notificationUrl,
345
+ alt: resourceTitle,
346
+ })) ?? undefined;
347
+ } catch (err) {
348
+ console.error(
349
+ "[share-resource] hero html resolver failed; omitting preview:",
350
+ err,
351
+ );
352
+ }
353
+ }
300
354
  const subject = `${actor} shared "${resourceTitle}" with you on ${appName}`;
301
355
  const { html, text } = renderEmail({
302
- brandName: appName,
356
+ brandName,
357
+ brandLogoUrl,
303
358
  preheader: subject,
304
359
  heading: "You've been given access",
305
360
  paragraphs: [
306
361
  `${emailStrong(actor)} has shared the ${reg.displayName} ${emailStrong(resourceTitle)} with you as a ${emailStrong(args.role)}.`,
307
362
  `Use the button below to open it. If prompted, sign in with ${emailStrong(principalId)}.`,
308
363
  ],
364
+ heroHtml,
309
365
  cta: { label: `Open ${reg.displayName}`, url: notificationUrl },
310
366
  footer: `You received this because ${actor} granted you ${args.role} access.`,
311
367
  });
312
- await sendEmail({ to: principalId, subject, html, text });
368
+ await sendEmail({
369
+ to: principalId,
370
+ subject,
371
+ html,
372
+ text,
373
+ fromName,
374
+ replyTo,
375
+ });
313
376
  } catch (err) {
314
377
  console.error(
315
378
  "[share-resource] failed to send share notification:",
@@ -17,6 +17,8 @@
17
17
  * });
18
18
  */
19
19
 
20
+ import type { UserProfile } from "../user-profile/shared.js";
21
+
20
22
  export interface ShareableResourceRegistration {
21
23
  /** Stable identifier used across actions, UI, and analytics. e.g. "document". */
22
24
  type: string;
@@ -36,6 +38,53 @@ export interface ShareableResourceRegistration {
36
38
  * when the caller does not pass a more specific resourceUrl.
37
39
  */
38
40
  getResourcePath?: (resource: any) => string | undefined;
41
+ /**
42
+ * Optional resolver for the share-notification email's brand logo. Return an
43
+ * absolute `https://` URL to override the default embedded Agent Native logo
44
+ * (e.g. the sharing org's own logo), or undefined to fall back. Receives the
45
+ * resource row being shared so the template can scope the logo to its org.
46
+ */
47
+ getLogoUrl?: (
48
+ resource: any,
49
+ ) => string | undefined | Promise<string | undefined>;
50
+ /**
51
+ * Optional resolver for the brand name shown beside the logo in the
52
+ * share-notification email header. Return a display name (e.g. the sharing
53
+ * org's name) to override the app name, or undefined to keep the default.
54
+ * Receives the resource row being shared.
55
+ */
56
+ getBrandName?: (
57
+ resource: any,
58
+ ) => string | undefined | Promise<string | undefined>;
59
+ /**
60
+ * Optional resolver for who the share-notification email appears to come
61
+ * from. `fromName` changes only the display name and keeps the configured,
62
+ * domain-verified sending address (e.g. "Alice via Clips"); `replyTo` routes
63
+ * replies to the sharer. `ctx.sender` is the account doing the sharing, so the
64
+ * template decides how to present them (name, email, avatar).
65
+ *
66
+ * Do not put a user's address in the sending address itself — SPF/DKIM sign
67
+ * the app's domain, so recipients would bounce or spam-filter it.
68
+ */
69
+ getSender?: (
70
+ resource: any,
71
+ ctx: { sender: UserProfile },
72
+ ) =>
73
+ | { fromName?: string; replyTo?: string }
74
+ | undefined
75
+ | Promise<{ fromName?: string; replyTo?: string } | undefined>;
76
+ /**
77
+ * Optional resolver for a preview block shown above the CTA in the
78
+ * share-notification email — e.g. a recording thumbnail with a play badge.
79
+ * Return trusted HTML (built by template code, dynamic values escaped) that
80
+ * is injected verbatim, or undefined to omit it. `ctx.href` is the resolved
81
+ * link to the resource; `ctx.alt` is its title. The template owns the entire
82
+ * preview markup so the generic share action stays app-agnostic.
83
+ */
84
+ getHeroHtml?: (
85
+ resource: any,
86
+ ctx: { href: string; alt?: string },
87
+ ) => string | undefined | Promise<string | undefined>;
39
88
  /**
40
89
  * Drizzle DB accessor from the template's server/db/index.ts. Required —
41
90
  * the framework-level share actions and access helpers call this to reach